1

我有一个包含 EditItemTemplate 和 InsertItemTemplate 的 ListView。这两种形式几乎共享它们的所有标记。例如:

<asp:listview runat="server" ... >
   <layouttemplate>...</layouttemplate>
   <itemtemplate>
      <p><%#Eval("Name")%></p>
      <p><%#Eval("Title")%></p>
       ...
   </itemtemplate>
   <insertitemtemplate>
      <p>Name: <asp:textbox runat=server text='<%#Bind("Name")%>' /></p>
      <p>Title: <asp:textbox runat=server text='<%#Bind("Title")%>' /></p>
      ...
      <asp:button runat=server commandname="Insert" text="Save" />
   </insertitemtemplate>
   <edititemtemplate>
      <p>Name: <asp:textbox runat=server text='<%#Bind("Name")%>' /></p>
      <p>Title: <asp:textbox runat=server text='<%#Bind("Title")%>' /></p>
      ...
      <asp:button runat=server commandname="Update" text="Save" />
   </edititemtemplate>
</asp:listview>

当然,实际上在插入和编辑模板中发生了很多事情(很多字段,包括格式化、验证等),我讨厌必须维护相同的标记两次。

我的第一个想法是将所有共享标记移动到用户控件(.ascx):

   <insertitemtemplate>
      <custom:myform runat=server />
      <asp:button runat=server commandname="Insert" text="Save" />
   </insertitemtemplate>
   <edititemtemplate>
      <custom:myform runat=server />
      <asp:button runat=server commandname="Update" text="Save" />
   </edititemtemplate>

不幸的是,双向绑定 (text='<%#Bind("Foo")%>') 仅在表单位于用户控件中时以一种方式工作(它不会将控件中的数据保留回数据库)。

另一种方法是将所有共享标记移动到包含文件。服务器端包含是对经典 ASP 的回归,但它们仍然可以在 ASP.NET 中工作,并且在这种情况下很有用,因为包含文件的内容就像页面上的标记一样被处理。

但是包含文件仍然有点做作,并且有它们的缺点(例如,VisualStudio 对它们不太满意)。有替代方案吗?

4

2 回答 2

2

我最终制作了一个自定义 ListView ,使这变得简单。如果没有 InsertItemTemplate,则 EditItemTemplate 用于两者:

    Private Sub ListView_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
        If Me.InsertItemTemplate Is Nothing Then
            Me.InsertItemTemplate = Me.EditItemTemplate
        End If
    End Sub

我还创建了一个自定义的“保存”按钮,可以根据需要在“更新”和“插入”之间切换其命令名:

    Private Sub SaveLinkButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click
        Dim _ListView As Controls.ListView = GetListView()
        If _ListView IsNot Nothing Then
            If Me.BindingContainer Is _ListView.EditItem Then
                Me.CommandName = "Update"
            Else
                Me.CommandName = "Insert"
            End If
        End If
    End Sub

GetListView上面的函数只是沿着按钮的父级向上走,直到找到一个 ListView。)

就是这样-希望这对某人有所帮助。

于 2010-02-04T20:15:32.293 回答
2

我参加聚会很晚了,但是对于任何寻求声明性解决方案的人,我最终做了以下事情(control是我的FormView):

if (control.EditItemTemplate == null)
{
    control.EditItemTemplate = control.InsertItemTemplate;
}

对于模板:

<InsertItemTemplate>

    ... template ...

    <asp:LinkButton Text="Insert" CommandName="Insert" runat="server" 
                    Visible='<%# Container.ItemType == ListViewItemType.InsertItem %>' />
    <asp:LinkButton Text="Update" CommandName="Update" runat="server"
                    Visible='<%# Container.ItemType == ListViewItemType.DataItem %>' />
    <asp:LinkButton Text="Cancel" CommandName="Cancel" runat="server" 
                    Visible='<%# Container.ItemType == ListViewItemType.DataItem %>' />
</InsertItemTemplate>

有趣的地方显然是:(Container.ItemType == ListViewItemType.DataItem和其他人)。这会根据模板类型正确设置按钮的可见性。

于 2015-05-20T10:08:21.727 回答