Cascading DropDownList binding in ASP.Net DetailsView templated control not working

86 Views Asked by At

I have two dropdown lists inside DetailsView, first dropdown DepartmentDropDown loads the data successfully from code behind using the following datasource

<asp:ObjectDataSource ID="dsDepartments" runat="server" SelectMethod="GetDepartments"
    TypeName="MyCode.DepartmentEmployeeAssociations">
</asp:ObjectDataSource>

and the second dropdown EmployeeDropDown uses another datasource based on Department selection in the first dropdown (commented code works and loads the details view but not the control parameter code):

<asp:ObjectDataSource ID="dsEmployees" runat="server" SelectMethod="GetAllEmployees"
    TypeName="MyCode.DepartmentEmployeeAssociations" DataObjectTypeName="Employee">
    <SelectParameters>
        <%--<asp:Parameter Name="deptId" Type="Int32" DefaultValue="7" />--%>
        <asp:ControlParameter ControlID="DepartmentDropDown" Name="deptId" PropertyName="SelectedValue" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

Here is the code in my GridView and DetailsView

<asp:Panel ID="AssociationView" runat="server" Visible="false">
    <asp:GridView ID="gvAssociations" runat="server" AutoGenerateColumns="False" CssClass="GridViewStyle"
        EmptyDataText="No rules defined" Width="100%" AllowPaging="True" GridLines="None"
        DataKeyNames="Id" EnableModelValidation="True" DataSourceID="dsAssociations"
        OnSelectedIndexChanged="gvAssociations_SelectedIndexChanged">
        <Columns>
            <asp:CommandField ShowSelectButton="true" SelectText="View" ItemStyle-Width="50px">
                <ItemStyle Width="50px"></ItemStyle>
            </asp:CommandField>
            <asp:BoundField DataField="Id" HeaderText="Id" SortExpression="Id" Visible="False" />
            <asp:BoundField DataField="Value1" HeaderText="Employee" SortExpression="Value1" Visible="false" />
            <asp:BoundField DataField="Value1Description" HeaderText="Employee" NullDisplayText="*" />
            <asp:BoundField DataField="Value2" HeaderText="Department" SortExpression="Value2" Visible="false" />
            <asp:BoundField DataField="Value2Description" HeaderText="Department" NullDisplayText="*" />
            <asp:CommandField ShowDeleteButton="True" />
        </Columns>
    </asp:GridView>
    <div class="DetailsContainer">
        <asp:DetailsView ID="dvAssociations" runat="server" Height="50px" GridLines="None"
            CellPadding="5" AutoGenerateRows="False" DataKeyNames="sId" EnableModelValidation="True"
            OnItemCreated="dvAssociations_ItemCreated" OnItemUpdating="dvAssociations_ItemUpdating"
            OnItemInserting="dvAssociations_ItemInserting">
            <Fields>
                <asp:BoundField DataField="Id" HeaderText="ID" ReadOnly="True" InsertVisible="False" Visible="false" />                 
                <asp:TemplateField HeaderText="Department">
                    <ItemTemplate>
                        <asp:DropDownList ID="DepartmentDropDown" runat="server" SelectedValue='<%# Bind("Value2") %>'
                            DataSourceID="dsDepartments" DataValueField="DepartmentId" DataTextField="Name"
                            Enabled="false" AutoPostBack="true">
                        </asp:DropDownList>
                    </ItemTemplate>
                    <EditItemTemplate>
                        <asp:DropDownList ID="DepartmentDropDown" runat="server" SelectedValue='<%# Bind("Value2") %>'
                            DataSourceID="dsDepartments" DataValueField="DepartmentId" DataTextField="Name"
                            Enabled="true" AutoPostBack="true">
                        </asp:DropDownList>
                    </EditItemTemplate>
                    <InsertItemTemplate>
                        <asp:DropDownList ID="DepartmentDropDown" runat="server" SelectedValue='<%# Bind("Value2") %>'
                            DataSourceID="dsDepartments" DataValueField="DepartmentId" DataTextField="Name"
                            Enabled="true" AutoPostBack="true">
                        </asp:DropDownList>
                    </InsertItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Employee">
                    <ItemTemplate>
                        <asp:DropDownList ID="EmployeeDropDown" runat="server"
                            DataSourceID="dsEmployees" DataValueField="EmployeeId" DataTextField="FullName"
                            Enabled="false">
                        </asp:DropDownList>
                    </ItemTemplate>
                    <EditItemTemplate>
                        <asp:DropDownList ID="EmployeeDropDown" runat="server"
                            DataSourceID="dsEmployees" DataValueField="EmployeeId" DataTextField="FullName"
                            Enabled="true">
                        </asp:DropDownList>
                    </EditItemTemplate>
                    <InsertItemTemplate>
                        <asp:DropDownList ID="EmployeeDropDown" runat="server"
                            DataSourceID="dsEmployees" DataValueField="EmployeeId" DataTextField="FullName"
                            Enabled="true">
                        </asp:DropDownList>
                    </InsertItemTemplate>
                </asp:TemplateField>
                <asp:CommandField ShowEditButton="True" ShowInsertButton="True" ShowDeleteButton="True" />
            </Fields>
        </asp:DetailsView>
    </div>
</asp:Panel>

and the code behind:

protected void gvAssociations_SelectedIndexChanged(object sender, EventArgs e)
{
    dvAssociations.PageIndex = gvAssociations.SelectedRow.DataItemIndex;
}

protected void dvAssociations_ItemCreated(object sender, EventArgs e)
{
     if (dvAssociations.DataItem == null)
         return;
     // Some checks
}

protected void dvAssociations_ItemUpdating(object sender, DetailsViewUpdateEventArgs e)
{
    //some code
}
protected void dvAssociations_ItemInserting(object sender, DetailsViewUpdateEventArgs e)
{
    e.NewValues["Value1"] = ((DropDownList)((DetailsView)sender).FindControl("EmployeeDropDown")).SelectedValue;
}

public List<Department> GetDepartments()
{
  // code to return List<Department> departments
  // other code
  return departments;
}

public List<Employee> GetAllEmployees(int deptId)
{
  // code to return List<Employee> employees
  // other code
  return employees;
}

I tried various suggestions that were given in other SO articles, but still not able to make this work. My page don't load when I have the control parameter added, but it works if I change it to a normal parameter.

<asp:ControlParameter ControlID="DepartmentDropDown" Name="deptId" PropertyName="SelectedValue" Type="Int32" />

I am not sure what it doesn't like about it, it doesn't seem to bind the data in the details view. I added the AutoPostBack to true to the first dropdown and removed the SelectedValue='<%# Bind("Value1") %>' from the second dropdown as suggested in other posts, but nothing seems to be working.

Any help would be appreciated.

1

There are 1 best solutions below

0
Sri Reddy On

I have finally made it work, it was a silly mistake but again I haven't worked on these asp components before. So, there was some learning here and hope this will help someone having similar issue.

Firstly, make sure that your data in the GridView is correct and the dropdown column has valid value and is in the dropdown list source.

Secondly, I had to move my ObjectDataSource for employees with in the itemtemplate

<asp:TemplateField HeaderText="Employee">
    <ItemTemplate>
        <asp:DropDownList ID="EmployeeDropDown" runat="server" SelectedValue='<%# Bind("Value1") %>'
            DataSourceID="dsEmployees" DataValueField="EmployeeId" DataTextField="FullName" Enabled="false">
        </asp:DropDownList>
        <asp:ObjectDataSource ID="dsEmployees" runat="server" SelectMethod="GetAllEmployees"
            TypeName="MyCode.DepartmentEmployeeAssociations" DataObjectTypeName="Employee">
            <SelectParameters>
                <asp:ControlParameter ControlID="DepartmentDropDown" Name="deptId" PropertyName="SelectedValue" Type="Int32" />
            </SelectParameters>
        </asp:ObjectDataSource>
    </ItemTemplate>
    <EditItemTemplate>
        <asp:DropDownList ID="EmployeeDropDown" runat="server" SelectedValue='<%# DataBinder.Eval (Container.DataItem, "Value1") %>'
            DataSourceID="dsEmployees" DataValueField="EmployeeId" DataTextField="FullName"
            Enabled="true">
        </asp:DropDownList>
        <asp:ObjectDataSource ID="dsEmployees" runat="server" SelectMethod="GetAllEmployees"
            TypeName="MyCode.DepartmentEmployeeAssociations" DataObjectTypeName="Employee">
            <SelectParameters>
                <asp:ControlParameter ControlID="DepartmentDropDown" Name="deptId" PropertyName="SelectedValue" Type="Int32" />
            </SelectParameters>
        </asp:ObjectDataSource>
    </EditItemTemplate>
    <InsertItemTemplate>
        <asp:DropDownList ID="EmployeeDropDown" runat="server" SelectedValue='<%# DataBinder.Eval (Container.DataItem, "Value1") %>'
            DataSourceID="dsEmployees" DataValueField="EmployeeId" DataTextField="FullName"
            Enabled="true">
        </asp:DropDownList>
        <asp:ObjectDataSource ID="dsEmployees" runat="server" SelectMethod="GetAllEmployees"
            TypeName="MyCode.DepartmentEmployeeAssociations" DataObjectTypeName="Employee">
            <SelectParameters>
                <asp:ControlParameter ControlID="DepartmentDropDown" Name="deptId" PropertyName="SelectedValue" Type="Int32" />
            </SelectParameters>
        </asp:ObjectDataSource>
    </InsertItemTemplate>                        
</asp:TemplateField>

Also, I have replaced SelectedValue='<%# Bind("Value1") %>' to SelectedValue='<%# DataBinder.Eval (Container.DataItem, "Value1") %>' in my EmployeeDropDown aspx code to make it simpler. Which means, no need to add this event handler dvAssociations_ItemInserting to the DetailsView.

But, I have another issue related to orphan data in the grid, which doesn't exist in the dropdown - which make the ItemTemplate fail to load. That's for another post, this post is done for now. Hope it helps other.