it-swarm.com.de

Gridview-Zeilenbearbeitung - Dynamische Bindung an eine DropDownList

Ich versuche, in einer ASP.NET 3.5-GridView einen ausgewählten Wert als Zeichenfolge anzuzeigen und eine DropDownList anzuzeigen, damit ich beim Bearbeiten einen Wert aus einer bestimmten Liste von Optionen auswählen kann. Scheint einfach genug?

Mein Gridview sieht so aus (vereinfacht):

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

Das Raster wird in Ordnung angezeigt, wenn es sich nicht im Bearbeitungsmodus befindet. Der ausgewählte PBX Typ zeigt seinen Wert im asp: Label-Steuerelement an. Kein Wunder, dass er dort angezeigt wird.

Ich lade die Werteliste für die DropDownList in ein lokales Element namens _pbxTypes Im Ereignis OnLoad des Formulars. Ich habe das überprüft - es funktioniert, die Werte sind da.

Jetzt ist meine Herausforderung: Wenn das Raster für eine bestimmte Zeile in den Bearbeitungsmodus wechselt, muss ich die in _pbxTypes Gespeicherte Liste der Nebenstellenanlagen binden.

Ganz einfach, dachte ich, nimm einfach das Dropdown-Listenobjekt im Ereignis RowEditing und hänge die Liste an:

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

Das Problem ist, dass ich durch den Aufruf von FindControl nie etwas zurückbekomme - es scheint, als ob ddlPBXTypeNS nicht existiert (oder nicht gefunden werden kann).

Was vermisse ich?? Muss etwas wirklich Dummes sein ... aber bis jetzt hat all mein Googeln, das Lesen von GridView-Steuerelementen und das Fragen von Freunden nicht geholfen.

Wer kann das fehlende Glied erkennen? ;-)

23
marc_s

Ganz einfach ... Du machst es falsch, weil zu diesem Zeitpunkt das Steuerelement nicht da ist:

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");
    }
}

Das heißt, es ist nur für eine DataRow (die aktuelle Zeile mit Daten) gültig, und wenn sie sich im Bearbeiten Modus befindet ... weil Sie jeweils nur eine Zeile bearbeiten. Die Funktion e.Row.FindControl("ddlPBXTypeNS") findet nur das gewünschte Steuerelement.

26
balexandre

Ich verwende eine ListView anstelle einer GridView in 3.5. Wenn der Benutzer bearbeiten möchte, habe ich das ausgewählte Element der Dropdown-Liste auf den vorhandenen Wert dieser Spalte für den Datensatz festgelegt. Ich kann auf die Dropdown-Liste im ItemDataBound-Ereignis zugreifen. Hier ist der Code:

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

Das Häkchen Antwort von Balexandre funktioniert hervorragend. Es wird jedoch ein Problem verursachen, wenn es an einige andere Situationen angepasst wird.

Ich habe es verwendet, um den Wert von zwei Beschriftungssteuerelementen - lblEditModifiedBy und lblEditModifiedOn - zu ändern, als ich eine Zeile bearbeitete, sodass die korrekten Werte für ModifiedBy und ModifiedOn im gespeichert wurden db auf 'Update'.

Wenn ich auf die Schaltfläche "Aktualisieren" geklickt habe, werden im Ereignis "RowUpdating" die neuen Werte angezeigt, die ich in die Liste "OldValues" eingegeben habe. Ich brauchte die wahren "alten Werte" als Original_-Werte beim Aktualisieren der Datenbank. (An das ObjectDataSource ist ein GridView angehängt.)

Die Lösung hierfür ist die Verwendung von Balexandres Code, jedoch in modifizierter Form in der gv_DataBound Veranstaltung:

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

Sie können SelectedValue verwenden:

<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