且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

.NET 4.5 WebForms:我真的仍然必须在FormView中指定所有3个模板吗?

更新时间:2023-02-14 22:17:18

与许多人所认为的相反,您仅需要在FormView中的 一个 模板,即EditItemTemplate. /p>

下面是一个简单的示例,显示了如何执行此操作(请注意,这与动态数据"的概念无关.).

通过这种方式,永远不会使用ReadOnly模式,因此不需要ItemTemplate. FormView将使用EditItemTemplate进行编辑和插入.

通过这种方式可以大大简化标记,并且当您对布局进行调整时,只需在一个模板中进行操作即可.

请注意,保存按钮没有CommandName.而是在FormView1_ItemCommand事件中确定命令(请参见代码).

还要注意,FormView的模式是在事件SqlDataSource1_Selected中确定的(请参见带有注释的代码).

我没有包括SqlDataSource1的标记,因为对于该标记没有什么特别的需要考虑.照常做就可以了.

    <asp:FormView ID="FormView1" runat="server" DataSourceID="SqlDataSource1"
      DataKeyNames="ApplicationId,UserId"
    >
      <EditItemTemplate>
        <asp:TextBox ID="txtFirstName" runat="server" Text='<%# Bind("firstName") %>'></asp:TextBox><br />
        <asp:TextBox ID="txtAge" runat="server" Text='<%# Bind("age") %>'></asp:TextBox><br />
        <asp:Button ID="btnSave" runat="server" Text="Save" />  
      </EditItemTemplate>
    </asp:FormView>

   Private Sub FormView1_ItemCommand(sender As Object, e As FormViewCommandEventArgs) Handles FormView1.ItemCommand
    Select Case FormView1.CurrentMode
      Case FormViewMode.Edit
        FormView1.UpdateItem(True)
      Case FormViewMode.Insert
        FormView1.InsertItem(True)
    End Select
  End Sub

  Private Sub SqlDataSource1_Selected(sender As Object, e As SqlDataSourceStatusEventArgs) Handles SqlDataSource1.Selected
    If e.AffectedRows = 0 Then
      ' nothing exists yet, so make formview ready to insert
      FormView1.ChangeMode(FormViewMode.Insert)
    Else
      ' something exists already, so make formview ready to edit
      FormView1.ChangeMode(FormViewMode.Edit)
    End If
  End Sub
 

Investigating the new strongly-typed, model-binding approach within ASP.NET 4.5 WebForms:

In Scott Hanselman's example of WebForms model binding (amongst others) I've seen the use of a FormView that opens in "Edit" mode, containing a number of DynamicControls e.g.

<asp:FormView runat="server" ID="MyForm" ... DefaultMode="Edit">
  <EditItemTemplate>
    <asp:DynamicControl runat="server" ID="Field1" DataField="Field1" Mode="Edit" />
    <asp:DynamicControl runat="server" ID="Field2" DataField="Field2" Mode="Edit" />
  </EditItemTemplate>
</asp:FormView> 

In my situation, my FormView's ItemTemplate, EditItemTemplate and InsertItemTemplate will be identical, except the ItemTemplate's controls will be in "ReadOnly" mode.

Do I (still) really need to provide three near-identical copies of the template within the FormView?

I'm happy to use DynamicControls, but the team here will never go for the "3x copy-paste" approach seemingly required for the FormView, especially for our large templates.

I had thought that maybe:

  • the DynamicControls could get their "Mode" from the containing FormView?
  • I could use something other than a FormView to contain my DynamicControls?
  • Should I manage the DynamicControls' mode in code-behind to avoid template duplication?

Any examples/ideas?

Contrary to what many believe, you need only one template in a FormView, the EditItemTemplate.

Below is a simple example showing how to do it (notice that this is not connected to the idea of "Dynamic Data".).

In this way of doing it, the ReadOnly mode is never used, and thus an ItemTemplate is not needed. And the FormView will use the EditItemTemplate for both editing and inserting.

This way to do it simplifies the markup a lot, and when you make adjustments to the layout, you only have to do it in the one single template.

Notice that the save-button has no CommandName. The command is instead determined in the FormView1_ItemCommand event (see code).

Also notice that the mode of the FormView is determined in the event SqlDataSource1_Selected (see that code, with comments).

I have not included the markup for the SqlDataSource1, because there is nothing special you need to think about for that one. Just make it as usual.

    <asp:FormView ID="FormView1" runat="server" DataSourceID="SqlDataSource1"
      DataKeyNames="ApplicationId,UserId"
    >
      <EditItemTemplate>
        <asp:TextBox ID="txtFirstName" runat="server" Text='<%# Bind("firstName") %>'></asp:TextBox><br />
        <asp:TextBox ID="txtAge" runat="server" Text='<%# Bind("age") %>'></asp:TextBox><br />
        <asp:Button ID="btnSave" runat="server" Text="Save" />  
      </EditItemTemplate>
    </asp:FormView>

  Private Sub FormView1_ItemCommand(sender As Object, e As FormViewCommandEventArgs) Handles FormView1.ItemCommand
    Select Case FormView1.CurrentMode
      Case FormViewMode.Edit
        FormView1.UpdateItem(True)
      Case FormViewMode.Insert
        FormView1.InsertItem(True)
    End Select
  End Sub

  Private Sub SqlDataSource1_Selected(sender As Object, e As SqlDataSourceStatusEventArgs) Handles SqlDataSource1.Selected
    If e.AffectedRows = 0 Then
      ' nothing exists yet, so make formview ready to insert
      FormView1.ChangeMode(FormViewMode.Insert)
    Else
      ' something exists already, so make formview ready to edit
      FormView1.ChangeMode(FormViewMode.Edit)
    End If
  End Sub