2013-12-08 7 views
0

У меня есть простой элемент управления DetailsView, связанный с источником данных, состоящим из двух запросов T-SQL (которые отлично работают). Однако, когда я пытаюсь изменить режим (в зависимости от идентификатора в URL-адресе) на «Редактировать» в событии Page_Load, ничего не отображается, пока «Вставка» работает нормально. Все кажется правильно привязанным к данным.change DetailsViewMode on Page_Load event

Кроме того, как мне получить доступ к значению BoundField (самому тексту) из кода (по какой-либо причине FindControl всегда возвращает null)? Я хочу иметь значение по умолчанию там, где загружается страница.

Markup:

<body> 
    <form id="form1" runat="server"> 
    <div class="register" runat="server"> 
     <asp:DetailsView ID="DV" runat="server" HorizontalAlign="Center" 
      Height="100px" Width="170px" 
      AutoGenerateRows="False" DataSourceID="RegisterUser" 
      OnItemCommand="Button_click" 
      OnItemInserted="Insert_click" OnItemUpdated="Edit_click"> 
      <Fields> 
       <asp:BoundField DataField="username" HeaderText="Name" 
        SortExpression="username" /> 
       <asp:TemplateField HeaderText="Password"> 
        <EditItemTemplate> 
         <asp:TextBox ID="Password" runat="server" TextMode="Password" Text='<%# Bind("userPassword") %>'></asp:TextBox> 
        </EditItemTemplate> 
       </asp:TemplateField> 
       <asp:BoundField DataField="userEmail" HeaderText="Email" 
        SortExpression="userEmail" /> 
       <asp:CommandField ShowInsertButton="True" ShowEditButton="True" /> 
      </Fields> 
     </asp:DetailsView> 
     <asp:SqlDataSource ID="RegisterUser" runat="server" 
      ConnectionString="<%$ ConnectionStrings:usersConnectionString %>" 
      InsertCommand="INSERT INTO korisnik(username, userPassword, userEmail) VALUES (@username, @userPassword, @userEmail)" 
      UpdateCommand="UPDATE korisnik SET userPassword = @userPassword, userEmail = @userEmail WHERE (username = @username)"> 
      <InsertParameters> 
       <asp:Parameter Name="username" Type="String" /> 
       <asp:Parameter Name="userPassword" Type="String" /> 
       <asp:Parameter Name="userEmail" Type="String" /> 
      </InsertParameters> 
      <UpdateParameters> 
       <asp:Parameter Name="userPassword" Type="String" /> 
       <asp:Parameter Name="userEmail" Type="String" /> 
       <asp:Parameter Name="username" Type="String" /> 
      </UpdateParameters> 
     </asp:SqlDataSource> 
     <asp:Label ID="Message_label" ForeColor="red" Visible="false" runat="server" Text="[messageLabel]"></asp:Label> 
    </div> 
    </form> 
</body> 

Code-за:

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!IsPostBack) 
    { 
     string id = Request.QueryString["id"]; 
     // EDIT mode 
     if (id == "Change_data_button") 
     { 
      DV.DefaultMode = DetailsViewMode.Edit; 
      //DV.DataSource = RegisterUser; 
      //DV.DataBind(); 
      DV.Fields[0].Visible = false; // preventing the value from being changed (one cannot change a username) 

      /* found this snippet somewhere but FindControl returns null */ 
      TextBox user; 
      user = (TextBox)DV.FindControl("username"); 
      user.Text = Session["LoggedUser"].ToString(); 
     } 
     // INSERT mode 
     else if (id == "Register_button") 
     { 
      DV.DefaultMode = DetailsViewMode.Insert; 
     } 
    } 
} 

ответ

0

Во-первых, я не вижу каких-либо настроек для SelectCommand в SqlDataSource управления имени RegisterUser, я не думаю, что вы будут иметь данные в DetailsView для редактирования в EditMode.

Таким образом, вы должны установить SelectCommand (также SelectParameters если есть), такие, как в следующем примере

<asp:SqlDataSource ID="RegisterUser" runat="server" 
      ConnectionString="<%$ ConnectionStrings:usersConnectionString %>" 
      SelectCommand="SELECT * FROM korisnik WHERE username = @username" 
      InsertCommand="INSERT INTO korisnik(username, userPassword, userEmail) VALUES (@username, @userPassword, @userEmail)" 
      UpdateCommand="UPDATE korisnik SET userPassword = @userPassword, userEmail = @userEmail WHERE (username = @username)"> 
    <SelectParameters> 
     <asp:Parameter Name="username" Type="String" /> 
    </SelectParameters> 
    <InsertParameters> 
     <asp:Parameter Name="username" Type="String" /> 
     <asp:Parameter Name="userPassword" Type="String" /> 
     <asp:Parameter Name="userEmail" Type="String" /> 
    </InsertParameters> 
    <UpdateParameters> 
     <asp:Parameter Name="userPassword" Type="String" /> 
     <asp:Parameter Name="userEmail" Type="String" /> 
     <asp:Parameter Name="username" Type="String" /> 
    </UpdateParameters> 
</asp:SqlDataSource> 

Secound, в обработчике Page_Load, эта линия user = (TextBox)DV.FindControl("username"); всегда должна быть пустой, потому что вы не имеете управляющие имена «имя пользователя», у вас есть только DataField с именем «username».

Если вы хотите скрыть поле имени пользователя в режиме редактирования, вам необходимо установить поле имени пользователя как Key of DetailView (DataKeyNames). Но я предлагаю вам установить имя пользователя только для чтения, а не скрывать его (установить ReadOnly="true" в BoundField). Финал, попытаться получить их значения в обработчик события ItemUpdating (OnItemUpdating установка)

Вот пример, как мое предложение:

<asp:DetailsView ID="DV" runat="server" HorizontalAlign="Center" 
    Height="100px" Width="170px" 
    AutoGenerateRows="False" DataSourceID="RegisterUser" 
    OnItemCommand="Button_click" 
    OnItemInserted="Insert_click" OnItemUpdated="Edit_click" 
    OnItemUpdating="DV_ItemUpdating" 
    DataKeyNames="username"> 
    <Fields> 
     <asp:BoundField DataField="username" HeaderText="Name" 
      SortExpression="username" 
      ReadOnly="true"/> 
     <asp:TemplateField HeaderText="Password"> 
      <EditItemTemplate> 
       <asp:TextBox ID="Password" runat="server" TextMode="Password" Text='<%# Bind("userPassword") %>'></asp:TextBox> 
      </EditItemTemplate> 
     </asp:TemplateField> 
     <asp:BoundField DataField="userEmail" HeaderText="Email" 
      SortExpression="userEmail" /> 
     <asp:CommandField ShowInsertButton="True" ShowEditButton="True" /> 
    </Fields> 
</asp:DetailsView> 

Code-behide:

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!IsPostBack) 
    { 
     string id = Request.QueryString["id"]; 
     // EDIT mode 
     if (id == "Change_data_button") 
     { 
      DV.DefaultMode = DetailsViewMode.Edit; 
     } 
     // INSERT mode 
     else if (id == "Register_button") 
     { 
      DV.DefaultMode = DetailsViewMode.Insert; 
     } 
    } 
} 
protected void DV_ItemUpdating(object sender, DetailsViewUpdateEventArgs e) 
{ 
    string username = e.Keys["username"].ToString(); 

    TextBox txtPassword = (TextBox)DV.FindControl("Password"); 
    string password = txtPassword.Text; 

    string email = e.NewValues["userEmail"].ToString(); 

    RegisterUser.UpdateParameters["userPassword"].DefaultValue = password; 
    RegisterUser.UpdateParameters["userEmail"].DefaultValue = email; 
    RegisterUser.UpdateParameters["username"].DefaultValue = username; 

    RegisterUser.Update(); 
} 
0

Вы должны использовать: DetailsView.ChangeMode() чтобы программно переключить управление DetailsView между режимом редактирования, вставки и только для чтения.

if (id == "Change_data_button") 
     { 
      DV.ChangeMode(DetailsViewMode.Edit); 
      //DV.DataSource = RegisterUser; 
      //DV.DataBind(); 
     ... 
     ... 
     } 

Кроме того, доступ к Bound значения полей, как ::

string _userName = DV.Rows[0].Cells[0].Text.ToString();