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?