I'm retrofitting an older web forms site with Model Binding using asp.net 4.5.
In a DetailsView
I have a drop down list that allows selection of a particular 'client' and another that allows selection of a particular 'project' that belongs to that client. So the drop down for project has to be filtered on the client number and if the user changes the client selection, I want to filter the project list by client number.
I couldn't figure out how to get the SelectedIndexChanged
method on the client ddl to fire the Select
method for the Project
, so I concluded the only way to do it was to filter the project ddl by client number in all cases. I am getting an error message when the client selection is made:
NullReferenceException was Unhandled by User Code
which point in my aspx directly to the ddl for Projects
.
This is an abbreviated version of the details view, you can see both the clients ddl and the projects ddl (I am operating in Edit mode):
<asp:DetailsView ID="AdministratorDetailsView" runat="server" AutoGenerateRows="False"
DataKeyNames="AdministratorNumber" ItemType="BusinessLogic.Administrator"
Width="99%"
SelectMethod="AdministratorDetailsView_GetItem"
UpdateMethod="AdministratorDetailsView_UpdateItem"
DeleteMethod="AdministratorDetailsView_DeleteItem"
FieldHeaderStyle-Width="30%" EditRowStyle-Width="99%"
InsertRowStyle-Width="70%" RowStyle-Width="99%" CssClass="admin"
AutoGenerateDeleteButton="true" AutoGenerateEditButton="true" >
<Fields>
<asp:TemplateField HeaderText="AdministratorCode" SortExpression="AdministratorCode">
<EditItemTemplate>
<asp:Label ID="AdministratorCode" Text="<%# Item.AdministratorCode%>" runat="server" />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="AdministratorCode" Text="<%# Item.AdministratorCode%>" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ClientNumber" SortExpression="ClientNumber">
<EditItemTemplate>
<asp:DropDownList ID="ddClients" runat="server"
AutoPostBack="true"
DataTextField="ClientName" DataValueField="ClientNumber"
ItemType="BusinessLogic.Client"
SelectMethod="ddClients_GetList"
SelectedValue="<%# Item.ClientNumber%>"
OnSelectedIndexChanged="AdministratorDetailsView_ddlClients_SelectedIndexChanged"/>
</EditItemTemplate>
<ItemTemplate>
<asp:DropDownList ID="ddClients" runat="server" Enabled="false"
DataTextField="ClientName" DataValueField="ClientNumber"
ItemType="BusinessLogic.Client"
SelectMethod="ddClients_GetList"
SelectedValue="<%# Item.ClientNumber%>"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Projects" >
<EditItemTemplate>
<asp:DropDownList ID="ddProjects" runat="server" AutoPostBack="true"
DataTextField="ProjectName" DataValueField="ProjectNumber"
ItemType="BusinessLogic.Project"
SelectMethod="ddProjects_GetList"
SelectedValue="<%# Item.ProjectNumber%>" />
</EditItemTemplate>
<ItemTemplate>
<asp:DropDownList ID="ddProjects" runat="server" Enabled="false"
DataTextField="ProjectName" DataValueField="ProjectNumber"
ItemType="BusinessLogic.Project"
SelectMethod="ddProjects_GetList"
SelectedValue="<%# Item.ProjectNumber%>"/>
</ItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
There are two SelectMethods
, one for each drop down list, and a selectedindexchaneged
method for clients:
Public Function ddClients_GetList() As List(Of BusinessLogic.Client)
Dim special As New List(Of Client)
special = CurrentClient.ClientList() 'add whole list
Dim NullClient As New Client()
NullClient.Load(0)
NullClient.ClientName = "<-Not Selected-->"
special.Add(NullClient) 'Had to have a client with 0 in the list since most admins don't have anything but 0 inthis field
Return special
End Function
Public Function ddProjects_GetList(<Control("ddClients")> ByVal ClientNumber As Integer) As List(Of BusinessLogic.Project)
Dim special As New List(Of Project)
If ClientNumber = 0 Then
special = CurrentProject.ProjectList() 'add whole list, refine it if Clients Drop Down selected
Else
special = CurrentProject.ProjectList(ClientNumber) 'add whole list, refine it if Clients Drop Down selected
End If
Dim NullProject As New Project()
NullProject.Load(0)
NullProject.ProjectName = "<-Not Selected-->"
special.Add(NullProject) 'Had to have a Project with 0 in the list since most admins don't have anything but 0 inthis field
Return special
End Function
Protected Sub AdministratorDetailsView_ddlClients_SelectedIndexChanged(sender As Object, e As EventArgs)
Dim ddlProj As DropDownList
ddlProj = AdministratorDetailsView.FindControl("ddProjects")
ddlProj.ItemType = "BusinessLogic.Project"
ddlProj.DataBind()
End Sub
All is well until the user selects a different client which triggers the SelectIndexChanged event and then we get to the DataBind(), where we get the null exception (ddlProj is found).
Need some ideas on how to refresh the projects list based on the new client selection.
How do I force ddProjects
to run its SelectMethod
again, to avoid the null reference and reload the control?