Question

Ok, I give up, I need your help. I thought this'd be simple!

In this scenario, Departments belong to Institutions. In my SQL database, it's a one-to-many relationship. People belong to both Departments and Institutions. I'm writing a page which allows the editing of a Person's details, where the Departments to which they can belong are restricted according to the Institution to which they belong. For example, if the HR Department is part of Institution A and the Finance Department is part of Institution B, if the Person is in Institution A they cannot belong to the Finance Department unless you first move them to Institution B.

I've got two dropdownlists in a FormView for editing the person's details - ddlEditInstitution and ddlEditDepartment. Quite simply, when the FormView first enters Edit mode, I want these two dropdownlists to show the Institution and Department to which that Person currently belongs. If you click on the Department dropdownlist you will only be able to choose from Departments belonging to that Institution. If you change the Institution in ddlInstitution, the available options in ddlDepartment should refresh to only show Departments belonging to the newly-selected Institution.

Right, some code. Here's my mark-up for the dropdownlists:

<tr>
    <td class="fieldlabel">Institution</td>                                
    <td><asp:DropDownList ID="ddlEditInstitution" runat="server" DataTextField="Name" DataValueField="ID" DataSourceID="SQLInstitution" SelectedValue='<%# Bind("InstitutionID")%>' CssClass="contactdetailseditfield" 
        AutoPostBack="True" OnSelectedIndexChanged="ddlEditInstitution_SelectedIndexChanged" /></td>
    <asp:SqlDataSource ID="SQLInstitution" runat="server" ConnectionString="<%$ ConnectionStrings:ContactsConnectionString %>"
        SelectCommand="SELECT * FROM [Institution] WHERE ([Deleted] = 0)" />
</tr>
<tr>
    <td class="fieldlabel">Department</td>
        <td><asp:UpdatePanel ID="upDepartment" runat="server" UpdateMode="conditional">
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="ddlEditInstitution" EventName="SelectedIndexChanged" />
            </Triggers>
            <ContentTemplate>
            <asp:DropDownList ID="ddlEditDepartment" runat="server" DataTextField="Name" DataValueField="ID" DataSourceID="SQLDepartment" CssClass="contactdetailseditfield" />
            <asp:SqlDataSource ID="SQLDepartment" runat="server" ConnectionString="<%$ ConnectionStrings:ContactsConnectionString %>"
                SelectCommand="SELECT * FROM [Department] WHERE ([Deleted] = 0) AND (Institution = @InstitutionID)">
                <SelectParameters>
                    <asp:ControlParameter ControlID="ddlEditInstitution" PropertyName="SelectedValue" Name="InstitutionID"  Type="Int32" />
                </SelectParameters>
            </asp:SqlDataSource>
        </ContentTemplate>
    </asp:UpdatePanel></td>                                
</tr>

And here's the code behind:

Protected Sub ddlEditInstitution_SelectedIndexChanged(sender As Object, e As EventArgs)

    ddlEditDepartment.SelectedValue = Nothing
        ddlEditDepartment.Items.Clear()
        ddlEditDepartment.DataBind()
        ddlEditDepartment.Items.Insert(0, New ListItem("--Select a department--", "-1"))
        ddlEditDepartment.SelectedIndex = 0

End Sub

This almost works perfectly. The problem is that when the FormView first enters Edit mode, ddlEditDepartment does not display the Person's current Department, it displays the first Department in the dropdownlist's items. This makes sense - I haven't set the SelectedValue of ddlEditDepartment. However, if I do so (as I did originally, when I thought this would be easy) by adding the property to ddlEditDepartment in the page mark-up, like so...

SelectedValue = '<%# Bind("DepartmentID")%>'

... then what happens is that if you select a different option from ddlInstitution, the databound items for ddlDepartment don't update. They continue to be the options linked to the old Institution. Presumably this is because the SelectedValue property of ddlEditDepartment is overriding everything else - the dropdownlist is bound to that column no matter what, it seems.

I've tried getting around this every which way I can think of, by manually changing the SelectedValue of ddlEditDepartment in code behind when changing ddlEditInstitution, by trying to set the SelectedValue of ddlEditDepartment in code behind to the Person's current Department when the FormView first enters Edit mode rather than explicitly... But nothing works.

I hate dropdownlists in ASP.NET. Can anybody tell me how to achieve what seems like a relatively simple effect?

Was it helpful?

Solution

Finally figured out a way to do this. In the DataBound event of the FormView, if it's in Edit Mode, I manually get the Person's current Department and set ddlEditDepartment to that value.

Protected Sub fvContactDetails_DataBound(sender As Object, e As EventArgs) Handles fvContactDetails.DataBound

    Dim dept As Integer = DataBinder.Eval(fvContactDetails.DataItem, "DepartmentID")
    If fvContactDetails.CurrentMode = FormViewMode.Edit Then
        ddlEditDepartment.SelectedValue = dept
    End If

End Sub
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top