1

EditItemTemplate と InsertItemTemplate を含む ListView があります。2 つのフォームは、ほとんどすべてのマークアップを共有しています。例えば:

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

もちろん、実際には、挿入テンプレートと編集テンプレートで多くのことが行われています (多くのフィールド、書式設定、検証など)。同じマークアップを 2 回維持する必要はありません。

私が最初に考えたのは、すべての共有マークアップをユーザー コントロール (.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 に答える