ASP.NET ListView with identical markup in EditItemTemplate and InsertItemTemplate

六眼飞鱼酱① 提交于 2019-12-22 00:27:03

问题


I have a ListView that includes an EditItemTemplate and an InsertItemTemplate. The two forms share almost all of their markup. For example:

<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>

Of course, in reality there's a lot going on in the insert and edit templates (lots of fields, with formatting, validation, etc.), and I hate to have to maintain the same markup twice.

My first thought was to move all the shared markup to a user control (.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>

Unfortunately, the two-way binding (text='<%#Bind("Foo")%>') only works one way when the form is in a user control (it doesn't persist the data from the controls back to the database).

An alternative would be to move all the shared markup to an include file. Server-side includes are a throwback to classic ASP, but they still work in ASP.NET and can be useful in situations like this, because the contents of the include file are treated just like markup that's right on the page.

But include files are still a little hokey, and have their disadvantages (e.g. VisualStudio isn't very comfortable with them). Is there an alternative?


回答1:


I've ended up making a custom ListView that makes this straightforward. If there is no InsertItemTemplate, then the EditItemTemplate is used for both:

    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

I've also created a custom "save" button that switches its commandname between "Update" and "Insert" as appropriate:

    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

(The GetListView function above just walks up the button's parents until it finds a ListView.)

That's it - hope this is helpful to someone.




回答2:


I'm very late to the party, but for anyone looking for a declarative solution, I ended up doing the following (control is my FormView):

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

And for the template:

<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>

Where the interesting bit is obviously: Container.ItemType == ListViewItemType.DataItem (and others). This correctly sets the visibility of the buttons according to the template type.



来源:https://stackoverflow.com/questions/2184757/asp-net-listview-with-identical-markup-in-edititemtemplate-and-insertitemtemplat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!