web-dev-qa-db-ja.com

Gridview行編集-DropDownListへの動的バインディング

ASP.NET 3.5 GridViewを取得して、表示時に選択した値を文字列として表示し、編集時にDropDownListを表示してオプションの特定のリストから値を選択できるようにしています。簡単そうに見える?

私のグリッドビューは次のようになります(簡略化):

<asp:GridView ID="grvSecondaryLocations" runat="server" 
              DataKeyNames="ID" OnInit="grvSecondaryLocations_Init" 
              OnRowCommand="grvSecondaryLocations_RowCommand" 
              OnRowCancelingEdit="grvSecondaryLocations_RowCancelingEdit"
              OnRowDeleting="grvSecondaryLocations_RowDeleting"
              OnRowEditing="grvSecondaryLocations_RowEditing" 
              OnRowUpdating="grvSecondaryLocations_RowUpdating"  >
<Columns>
    <asp:TemplateField>
         <ItemTemplate>
              <asp:Label ID="lblPbxTypeCaption" runat="server" 
                                 Text='<%# Eval("PBXTypeCaptionValue") %>' />
         </ItemTemplate>
         <EditItemTemplate>
                      <asp:DropDownList ID="ddlPBXTypeNS" runat="server" 
                               Width="200px" 
                               DataTextField="CaptionValue" 
                               DataValueField="OID" />
         </EditItemTemplate>
    </asp:TemplateField>
</asp:GridView>

編集モードではない場合、グリッドは正常に表示されます-選択されたPBX=タイプはasp:Labelコントロールにその値を表示します。そこに驚きはありません。

DropDownListの値のリストを、フォームのOnLoadイベントの_pbxTypesというローカルメンバーにロードします。私はこれを検証しました-それは動作します、値はそこにあります。

ここで私の課題は、グリッドが特定の行の編集モードになると、_pbxTypesに格納されているPBXのリストをバインドする必要があることです。

十分に単純な、私は思った-RowEditingイベントでドロップダウンリストオブジェクトを取得し、リストを添付します。

protected void grvSecondaryLocations_RowEditing(object sender, GridViewEditEventArgs e)
{
    grvSecondaryLocations.EditIndex = e.NewEditIndex;

    GridViewRow editingRow = grvSecondaryLocations.Rows[e.NewEditIndex];

    DropDownList ddlPbx = (editingRow.FindControl("ddlPBXTypeNS") as DropDownList);
    if (ddlPbx != null)
    {
        ddlPbx.DataSource = _pbxTypes;
        ddlPbx.DataBind();
    }

    .... (more stuff)
}

問題は-FindControl呼び出しから何も返されない-ddlPBXTypeNSが存在しない(または見つからない)ようです。

私は何が欠けていますか?本当にばかげたものである必要があります....しかし、これまでのところ、すべてのグーグル、GridViewコントロールを読んで、仲間に尋ねることは助けになりませんでした。

誰がミッシングリンクを見つけることができますか? ;-)

23
marc_s

非常に簡単です...あなたはそれを間違っています、なぜならそのイベントによってコントロールがそこにないからです:

_protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow && 
        (e.Row.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
    { 
        // Here you will get the Control you need like:
        DropDownList dl = (DropDownList)e.Row.FindControl("ddlPBXTypeNS");
    }
}
_

つまり、DataRow(実際にはデータのある行)に対してのみ有効であり、編集モードの場合は、一度に1行しか編集できないためです。 e.Row.FindControl("ddlPBXTypeNS")は、必要なコントロールのみを検索します。

26
balexandre

3.5では、GridViewの代わりにListViewを使用しています。ユーザーが編集したい場合、ドロップダウンの選択された項目をレコードのその列の既存の値に設定しました。 ItemDataBoundイベントのドロップダウンにアクセスできます。コードは次のとおりです。

protected void listViewABC_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    // This stmt is used to execute the code only in case of edit 
    if (((ListView)(sender)).EditIndex != -1 && ((ListViewDataItem)(e.Item)).DisplayIndex == ((ListView)(sender)).EditIndex)
    {
        ((DropDownList)(e.Item.FindControl("ddlXType"))).SelectedValue = ((MyClass)((ListViewDataItem)e.Item).DataItem).XTypeId.ToString();
        ((DropDownList)(e.Item.FindControl("ddlIType"))).SelectedValue = ((MyClass)((ListViewDataItem)e.Item).DataItem).ITypeId.ToString();
    }
}
1
Rashmi Pandit
protected void grvSecondaryLocations_RowEditing(object sender, GridViewEditEventArgs e)  
{  
    grvSecondaryLocations.EditIndex = e.NewEditIndex;  

    DropDownList ddlPbx = (DropDownList)(grvSecondaryLocations.Rows[grvSecondaryLocations.EditIndex].FindControl("ddlPBXTypeNS"));
    if (ddlPbx != null)  
    {  
        ddlPbx.DataSource = _pbxTypes;  
        ddlPbx.DataBind();  
    }  

    .... (more stuff)  
}
1
ALRamarao

チェック済みの balexandreからの回答 は非常に効果的です。しかし、他の状況に適応すると問題が発生します。

行を編集しているときに2つのラベルコントロールの値を変更するために使用しました-lblEditModifiedByおよびlblEditModifiedOn-正しいModifiedByおよびModifiedOnがdbに保存されるように '更新'。

[更新]ボタンをクリックすると、RowUpdatingイベントで、OldValuesリストに入力した新しい値が表示されました。データベースを更新するときに、Original_値として真の「古い値」が必要でした。 (ObjectDataSourceGridViewが接続されています。)

これを修正するには、balexandreのコードを使用しますが、gv_DataBoundイベント:

protected void gv_DataBound(object sender, EventArgs e)
{
    foreach (GridViewRow gvr in gv.Rows)
    {
        if (gvr.RowType == DataControlRowType.DataRow && (gvr.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
        {
            // Here you will get the Control you need like:
            ((Label)gvr.FindControl("lblEditModifiedBy")).Text = Page.User.Identity.Name;
            ((Label)gvr.FindControl("lblEditModifiedOn")).Text = DateTime.Now.ToString();
        }
    }
}
0
gleapman

SelectedValueを使用できます。

<EditItemTemplate>
    <asp:DropDownList ID="ddlPBXTypeNS"
                      runat="server"
                      Width="200px"
                      DataSourceID="YDS"
                      DataTextField="CaptionValue"
                      DataValueField="OID"
                      SelectedValue='<%# Bind("YourForeignKey") %>' />
    <asp:YourDataSource ID="YDS" ...../>
</EditItemTemplate>
0
Hossein Margani