views:

30140

answers:

6

This is driving me crazy :-)

I'm trying to get a ASP.NET 3.5 GridView to show a selected value as string when being displayed, and to show a DropDownList to allow me to pick a value from a given list of options when being edited. Seems simple enough?

My gridview looks like this (simplified):

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

The grid gets displayed OK when not in editing mode - the selected PBX type shows its value in the asp:Label control. No surprise there.

I load the list of values for the DropDownList into a local member called _pbxTypes in the OnLoad event of the form. I verified this - it works, the values are there.

Now my challenge is: when the grid goes into editing mode for a particular row, I need to bind the list of PBX's stored in _pbxTypes.

Simple enough, I thought - just grab the drop down list object in the RowEditing event and attach the list:

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

Trouble is - I never get anything back from the FindControl call - seems like the ddlPBXTypeNS doesn't exist (or can't be found).

What am I missing?? Must be something really stupid.... but so far, all my Googling, reading up on GridView controls, and asking buddies hasn't helped.

Who can spot the missing link? ;-)

Marc

A: 

I am using a ListView instead of a GridView in 3.5. When the user wants to edit I have set the selected item of the dropdown to the exising value of that column for the record. I am able to access the dropdown in the ItemDataBound event. Here's the 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();
    }
}
Rashmi Pandit
it's not a List is a gridView!
balexandre
exactly - and I really don't want to change it just to get it to work, if ever possible..... thanks anyway!
marc_s
balexandre ... i hav already mentioned its NOT a gridview ... this was just an FYI not a soln ... it will be better if u guys learn to give -ve points to 'incorrect answers' rather than 'other solns or fyis'
Rashmi Pandit
+6  A: 

quite easy ... you're doing it wrong, cause by that Event the control is not there...

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

That if will only be valid for a DataRow (the actually row with data) and if it's in Edit mode... because you only Edit one row at a time the e.Row.FindControl("ddlPBXTypeNS") will only find the control that you want.

Hope that helps.

balexandre
Tricky.... I get this event, but the RowState is "Alternate | Edit" - so your IF never is true :-)
marc_s
OK, I changed your if to check for the "Edit" bit being set (ignoring any other bits that might be set) and now it works like a charm! Thanks a heap!!
marc_s
just changed the code :)
balexandre
marc_s
there are so many ways to accomplish the same :) but I prefer your idea, it's cleaner! ... edited ;)
balexandre
A: 

you can use SelectedValue:

     <EditItemTemplate>
         <asp:DropDownList ID="ddlPBXTypeNS" 
                           runat="server" 
                           Width="200px" 
                           DataSourceID="YDS"
                           DataTextField="CaptionValue" 
                           DataValueField="OID"
                           SelectedValue='<%# Bind("YourFoerignKey") %>' />
         <asp:YourDataSource ID="YDS" ...../>
 </EditItemTemplate>
Hossein Margani
A: 
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)  
}
ALRamarao
A: 

The checked answer from balexandre works great. But, it will create a problem if adapted to some other situations.

I used it to change the value of two label controls - lblEditModifiedBy and lblEditModifiedOn - when I was editing a row, so that the correct ModifiedBy and ModifiedOn would be saved to the db on 'Update'.

When I clicked the 'Update' button, in the RowUpdating event it showed the new values I entered in the OldValues list. I needed the true "old values" as Original_ values when updating the database. (There's an ObjectDataSource attached to the gridview.)

The fix to this is using balexandre's code, but in a modified form in the gv_DataBound event:

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();
        }
    }
}
gleapman
A: 

HI i have tried the above given solutions but it still gives an error

"Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index"

My Code is as below:

Private Sub gvBenificiary_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles gvBenificiary.PreRender

   If gvBenificiary.EditIndex <> -1 Then

LoadFamilyMembers(**CType(gvBenificiary.Rows(gvBenificiary.EditIndex).FindControl("ddlEmpFamMemberedt")**, DropDownList))


   End If
End Sub
krishnakantj