472,802 Members | 1,379 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,802 software developers and data experts.

Interdependent DropDownLists (with declarative data binding)

I have an ASP.NET 2.0 page with two DropDownLists. I am using declarative
data binding wherever possible and trying to minimize the use of code. The
list of values in DropDownList DDL2 should be (filtered) dependent upon the
selection in DDL1. I think this inevitably needs some code, but I'd be happy
to be told otherwise!
I have some code to handle OnSelectedIndexChanged for DDL1 that sets the
FilterExpression associated with the DataSourceID of DDL2. My problem is that
after the code executes, I get an InvalidOperationException error that says
"Databinding methods such as Eval(), XPath(), and Bind() can only be used in
the context of a databound control."
How can I avoid this?
Nov 19 '05 #1
9 5271
Yes you can. I just tested it on my PC. If you use Binding to DataAccess
Layer http://66.129.71.130/QuickStartv20/a...jects.aspx#dal

Then you would have a parameterized query for selecting the items of the
second dropdown list. Something like this:

<!-- this the first dropdown list --->
<asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID="ObjectDataSource1" DataTextField="CategoryName"
DataValueField="CategoryID" AutoPostBack="True">
</asp:DropDownList>
<!-- this is the dependent dropdown list --->
<asp:DropDownList ID="DropDownList2" runat="server"
DataSourceID="ObjectDataSource2" DataTextField="Description"
DataValueField="CategoryID" AutoPostBack="True">
</asp:DropDownList>
<!-- this is the objectDataSource for the first dropdownlist --->
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
SelectMethod="getMyFirstList"></asp:ObjectDataSource>
<!-- this is the objectDataSource for the second dropdownlist. It receives
a parameter from the first list --->
<asp:ObjectDataSource ID="ObjectDataSource2" runat="server"
TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
SelectMethod="getMySecondList">
<SelectParameters>
<asp:ControlParameter ControlID="DropDownList1" Name="CategoryID"
PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Timm" wrote:
I have an ASP.NET 2.0 page with two DropDownLists. I am using declarative
data binding wherever possible and trying to minimize the use of code. The
list of values in DropDownList DDL2 should be (filtered) dependent upon the
selection in DDL1. I think this inevitably needs some code, but I'd be happy
to be told otherwise!
I have some code to handle OnSelectedIndexChanged for DDL1 that sets the
FilterExpression associated with the DataSourceID of DDL2. My problem is that
after the code executes, I get an InvalidOperationException error that says
"Databinding methods such as Eval(), XPath(), and Bind() can only be used in
the context of a databound control."
How can I avoid this?

Nov 19 '05 #2
Correction: Look in the Binding to a Visual Studio DataSet (instead of the
Data Access layer) in the Quick Start tutorials that I gave its link.

"Phillip Williams" wrote:
Yes you can. I just tested it on my PC. If you use Binding to DataAccess
Layer http://66.129.71.130/QuickStartv20/a...jects.aspx#dal

Then you would have a parameterized query for selecting the items of the
second dropdown list. Something like this:

<!-- this the first dropdown list --->
<asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID="ObjectDataSource1" DataTextField="CategoryName"
DataValueField="CategoryID" AutoPostBack="True">
</asp:DropDownList>
<!-- this is the dependent dropdown list --->
<asp:DropDownList ID="DropDownList2" runat="server"
DataSourceID="ObjectDataSource2" DataTextField="Description"
DataValueField="CategoryID" AutoPostBack="True">
</asp:DropDownList>
<!-- this is the objectDataSource for the first dropdownlist --->
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
SelectMethod="getMyFirstList"></asp:ObjectDataSource>
<!-- this is the objectDataSource for the second dropdownlist. It receives
a parameter from the first list --->
<asp:ObjectDataSource ID="ObjectDataSource2" runat="server"
TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
SelectMethod="getMySecondList">
<SelectParameters>
<asp:ControlParameter ControlID="DropDownList1" Name="CategoryID"
PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Timm" wrote:
I have an ASP.NET 2.0 page with two DropDownLists. I am using declarative
data binding wherever possible and trying to minimize the use of code. The
list of values in DropDownList DDL2 should be (filtered) dependent upon the
selection in DDL1. I think this inevitably needs some code, but I'd be happy
to be told otherwise!
I have some code to handle OnSelectedIndexChanged for DDL1 that sets the
FilterExpression associated with the DataSourceID of DDL2. My problem is that
after the code executes, I get an InvalidOperationException error that says
"Databinding methods such as Eval(), XPath(), and Bind() can only be used in
the context of a databound control."
How can I avoid this?

Nov 19 '05 #3
Thanks Phillip, but I have tried something similar already and couldn't get
it to work, perhaps because my data sources are SqlDataSource (it might have
been helpful if I'd mentioned that in the first place!). Also note, DDL1 and
DDL2 are controls in TemplateFields within a DetailsView.

"Phillip Williams" wrote:
Correction: Look in the Binding to a Visual Studio DataSet (instead of the
Data Access layer) in the Quick Start tutorials that I gave its link.

"Phillip Williams" wrote:
Yes you can. I just tested it on my PC. If you use Binding to DataAccess
Layer http://66.129.71.130/QuickStartv20/a...jects.aspx#dal

Then you would have a parameterized query for selecting the items of the
second dropdown list. Something like this:

<!-- this the first dropdown list --->
<asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID="ObjectDataSource1" DataTextField="CategoryName"
DataValueField="CategoryID" AutoPostBack="True">
</asp:DropDownList>
<!-- this is the dependent dropdown list --->
<asp:DropDownList ID="DropDownList2" runat="server"
DataSourceID="ObjectDataSource2" DataTextField="Description"
DataValueField="CategoryID" AutoPostBack="True">
</asp:DropDownList>
<!-- this is the objectDataSource for the first dropdownlist --->
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
SelectMethod="getMyFirstList"></asp:ObjectDataSource>
<!-- this is the objectDataSource for the second dropdownlist. It receives
a parameter from the first list --->
<asp:ObjectDataSource ID="ObjectDataSource2" runat="server"
TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
SelectMethod="getMySecondList">
<SelectParameters>
<asp:ControlParameter ControlID="DropDownList1" Name="CategoryID"
PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Timm" wrote:
I have an ASP.NET 2.0 page with two DropDownLists. I am using declarative
data binding wherever possible and trying to minimize the use of code. The
list of values in DropDownList DDL2 should be (filtered) dependent upon the
selection in DDL1. I think this inevitably needs some code, but I'd be happy
to be told otherwise!
I have some code to handle OnSelectedIndexChanged for DDL1 that sets the
FilterExpression associated with the DataSourceID of DDL2. My problem is that
after the code executes, I get an InvalidOperationException error that says
"Databinding methods such as Eval(), XPath(), and Bind() can only be used in
the context of a databound control."
How can I avoid this?

Nov 19 '05 #4
I have tried the following using SqlDataSource against the NorthWind database
and it worked fine:

<table>
<tr>
<td>Region</td>
<td>
<asp:DropDownList ID="ddlRegions" runat=server DataSourceID
="SqlRegions" DataTextField="RegionDescription"
DataValueField="RegionID" AutoPostBack="True"></asp:DropDownList>
<asp:SqlDataSource ID="SqlRegions" runat="server"
ConnectionString="<%$
ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT RegionID, RegionDescription FROM
Region">
</asp:SqlDataSource>
</td>
</tr>
<tr>
<td>Territory</td>
<td>
<asp:DropDownList ID="ddlTerritories2" runat=server DataSourceID
="SqlTerritories" DataTextField="TerritoryDescription"
DataValueField="TerritoryID"></asp:DropDownList>
<asp:SqlDataSource ID="SqlTerritories" runat="server"
ConnectionString="<%$
ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT TerritoryID, TerritoryDescription FROM
Territories WHERE (RegionID = @RegionID)">
<SelectParameters>
<asp:ControlParameter Name="RegionID" ControlID="ddlRegions"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>

</td>
</tr>

</table>
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Timm" wrote:
Thanks Phillip, but I have tried something similar already and couldn't get
it to work, perhaps because my data sources are SqlDataSource (it might have
been helpful if I'd mentioned that in the first place!). Also note, DDL1 and
DDL2 are controls in TemplateFields within a DetailsView.

"Phillip Williams" wrote:
Correction: Look in the Binding to a Visual Studio DataSet (instead of the
Data Access layer) in the Quick Start tutorials that I gave its link.

"Phillip Williams" wrote:
Yes you can. I just tested it on my PC. If you use Binding to DataAccess
Layer http://66.129.71.130/QuickStartv20/a...jects.aspx#dal

Then you would have a parameterized query for selecting the items of the
second dropdown list. Something like this:

<!-- this the first dropdown list --->
<asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID="ObjectDataSource1" DataTextField="CategoryName"
DataValueField="CategoryID" AutoPostBack="True">
</asp:DropDownList>
<!-- this is the dependent dropdown list --->
<asp:DropDownList ID="DropDownList2" runat="server"
DataSourceID="ObjectDataSource2" DataTextField="Description"
DataValueField="CategoryID" AutoPostBack="True">
</asp:DropDownList>
<!-- this is the objectDataSource for the first dropdownlist --->
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
SelectMethod="getMyFirstList"></asp:ObjectDataSource>
<!-- this is the objectDataSource for the second dropdownlist. It receives
a parameter from the first list --->
<asp:ObjectDataSource ID="ObjectDataSource2" runat="server"
TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
SelectMethod="getMySecondList">
<SelectParameters>
<asp:ControlParameter ControlID="DropDownList1" Name="CategoryID"
PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Timm" wrote:

> I have an ASP.NET 2.0 page with two DropDownLists. I am using declarative
> data binding wherever possible and trying to minimize the use of code. The
> list of values in DropDownList DDL2 should be (filtered) dependent upon the
> selection in DDL1. I think this inevitably needs some code, but I'd be happy
> to be told otherwise!
> I have some code to handle OnSelectedIndexChanged for DDL1 that sets the
> FilterExpression associated with the DataSourceID of DDL2. My problem is that
> after the code executes, I get an InvalidOperationException error that says
> "Databinding methods such as Eval(), XPath(), and Bind() can only be used in
> the context of a databound control."
> How can I avoid this?

Nov 19 '05 #5
But how can the ControlID of the SelectParameter refer to a DropDownList in a
TemplateField of the DetailsView?

"Phillip Williams" wrote:
I have tried the following using SqlDataSource against the NorthWind database
and it worked fine:

<table>
<tr>
<td>Region</td>
<td>
<asp:DropDownList ID="ddlRegions" runat=server DataSourceID
="SqlRegions" DataTextField="RegionDescription"
DataValueField="RegionID" AutoPostBack="True"></asp:DropDownList>
<asp:SqlDataSource ID="SqlRegions" runat="server"
ConnectionString="<%$
ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT RegionID, RegionDescription FROM
Region">
</asp:SqlDataSource>
</td>
</tr>
<tr>
<td>Territory</td>
<td>
<asp:DropDownList ID="ddlTerritories2" runat=server DataSourceID
="SqlTerritories" DataTextField="TerritoryDescription"
DataValueField="TerritoryID"></asp:DropDownList>
<asp:SqlDataSource ID="SqlTerritories" runat="server"
ConnectionString="<%$
ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT TerritoryID, TerritoryDescription FROM
Territories WHERE (RegionID = @RegionID)">
<SelectParameters>
<asp:ControlParameter Name="RegionID" ControlID="ddlRegions"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>

</td>
</tr>

</table>
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Timm" wrote:
Thanks Phillip, but I have tried something similar already and couldn't get
it to work, perhaps because my data sources are SqlDataSource (it might have
been helpful if I'd mentioned that in the first place!). Also note, DDL1 and
DDL2 are controls in TemplateFields within a DetailsView.

"Phillip Williams" wrote:
Correction: Look in the Binding to a Visual Studio DataSet (instead of the
Data Access layer) in the Quick Start tutorials that I gave its link.

"Phillip Williams" wrote:

> Yes you can. I just tested it on my PC. If you use Binding to DataAccess
> Layer http://66.129.71.130/QuickStartv20/a...jects.aspx#dal
>
> Then you would have a parameterized query for selecting the items of the
> second dropdown list. Something like this:
>
> <!-- this the first dropdown list --->
> <asp:DropDownList ID="DropDownList1" runat="server"
> DataSourceID="ObjectDataSource1" DataTextField="CategoryName"
> DataValueField="CategoryID" AutoPostBack="True">
> </asp:DropDownList>
> <!-- this is the dependent dropdown list --->
> <asp:DropDownList ID="DropDownList2" runat="server"
> DataSourceID="ObjectDataSource2" DataTextField="Description"
> DataValueField="CategoryID" AutoPostBack="True">
> </asp:DropDownList>
> <!-- this is the objectDataSource for the first dropdownlist --->
> <asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
> TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
> SelectMethod="getMyFirstList"></asp:ObjectDataSource>
> <!-- this is the objectDataSource for the second dropdownlist. It receives
> a parameter from the first list --->
> <asp:ObjectDataSource ID="ObjectDataSource2" runat="server"
> TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
> SelectMethod="getMySecondList">
> <SelectParameters>
> <asp:ControlParameter ControlID="DropDownList1" Name="CategoryID"
> PropertyName="SelectedValue"
> Type="String" />
> </SelectParameters>
> </asp:ObjectDataSource>
> --
> HTH,
> Phillip Williams
> http://www.societopia.net
> http://www.webswapp.com
>
>
> "Timm" wrote:
>
> > I have an ASP.NET 2.0 page with two DropDownLists. I am using declarative
> > data binding wherever possible and trying to minimize the use of code. The
> > list of values in DropDownList DDL2 should be (filtered) dependent upon the
> > selection in DDL1. I think this inevitably needs some code, but I'd be happy
> > to be told otherwise!
> > I have some code to handle OnSelectedIndexChanged for DDL1 that sets the
> > FilterExpression associated with the DataSourceID of DDL2. My problem is that
> > after the code executes, I get an InvalidOperationException error that says
> > "Databinding methods such as Eval(), XPath(), and Bind() can only be used in
> > the context of a databound control."
> > How can I avoid this?

Nov 19 '05 #6
Hi Timm,

I have placed the same code inside this sample of a DetailsView from the
Quickstart tutorials
http://66.129.71.130/QuickStartv20/u...lsEdit_cs.aspx
and it still worked. Can you post the code the you have not working?

Here it is the complete code that I tried:
<b>Choose a state:</b>
<asp:DropDownList ID="DropDownList1" DataSourceID="SqlDataSource2"
AutoPostBack="true"
DataTextField="state" runat="server"
OnSelectedIndexChanged="DropDownList1_SelectedInde xChanged" />
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
SelectCommand="SELECT DISTINCT [state] FROM [authors]"
ConnectionString="<%$ ConnectionStrings:Pubs %>" />
<br />
<br />
<table>
<tr>
<td valign="top">
<asp:GridView ID="GridView1" AllowSorting="True"
AllowPaging="True" runat="server"
DataSourceID="SqlDataSource1" DataKeyNames="au_id"
AutoGenerateColumns="False" Width="427px"
OnSelectedIndexChanged="GridView1_SelectedIndexCha nged"
OnSorted="GridView1_Sorted" OnPageIndexChanged="GridView1_PageIndexChanged">
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:BoundField DataField="au_id" HeaderText="au_id"
ReadOnly="True" SortExpression="au_id" />
<asp:BoundField DataField="au_lname" HeaderText="au_lname"
SortExpression="au_lname" />
<asp:BoundField DataField="au_fname" HeaderText="au_fname"
SortExpression="au_fname" />
<asp:BoundField DataField="state" HeaderText="state"
SortExpression="state" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors]
WHERE ([state] = @state)"
ConnectionString="<%$ ConnectionStrings:Pubs %>">
<SelectParameters>
<asp:ControlParameter ControlID="DropDownList1" Name="state"
PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</td>
<td valign="top">
<asp:DetailsView AutoGenerateRows="False" DataKeyNames="au_id"
OnItemUpdated="DetailsView1_ItemUpdated" DataSourceID="SqlDataSource3"
HeaderText="Author Details" ID="DetailsView1" runat="server"
Width="275px">
<Fields>
<asp:BoundField DataField="au_id" HeaderText="au_id"
ReadOnly="True" SortExpression="au_id" />
<asp:BoundField DataField="au_lname" HeaderText="au_lname"
SortExpression="au_lname" />
<asp:BoundField DataField="au_fname" HeaderText="au_fname"
SortExpression="au_fname" />
<asp:BoundField DataField="phone" HeaderText="phone"
SortExpression="phone" />
<asp:BoundField DataField="address" HeaderText="address"
SortExpression="address" />
<asp:BoundField DataField="city" HeaderText="city"
SortExpression="city" />
<asp:BoundField DataField="state" HeaderText="state"
SortExpression="state" />
<asp:BoundField DataField="zip" HeaderText="zip"
SortExpression="zip" />
<asp:TemplateField >
<ItemTemplate>
<asp:Label runat=server ID="lblRegion" Text='<%#
Eval("City") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate >
<table>
<tr>
<td>Region</td>
<td>
<asp:DropDownList ID="ddlRegions" runat=server
DataSourceID ="SqlRegions" DataTextField="RegionDescription"
DataValueField="RegionID"
AutoPostBack="True"></asp:DropDownList>
<asp:SqlDataSource ID="SqlRegions" runat="server"
ConnectionString="<%$
ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT RegionID,
RegionDescription FROM Region">
</asp:SqlDataSource>
</td>
</tr>
<tr>
<td>Territory</td>
<td>
<asp:DropDownList ID="ddlTerritories2"
runat=server DataSourceID ="SqlTerritories"
DataTextField="TerritoryDescription"
DataValueField="TerritoryID"></asp:DropDownList>
<asp:SqlDataSource ID="SqlTerritories"
runat="server"
ConnectionString="<%$
ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT TerritoryID,
TerritoryDescription FROM Territories WHERE (RegionID = @RegionID)">
<SelectParameters>
<asp:ControlParameter Name="RegionID"
ControlID="ddlRegions" PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>

</td>
</tr>

</table>
</EditItemTemplate>
</asp:TemplateField>
<asp:CheckBoxField DataField="contract" HeaderText="contract"
SortExpression="contract" />
<asp:CommandField ShowEditButton="True" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="SqlDataSource3" runat="server"
ConnectionString="<%$ ConnectionStrings:Pubs %>"
SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone],
[address], [city], [state], [zip], [contract] FROM [authors] WHERE ([au_id] =
@au_id)"
UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname,
[au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] =
@city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] =
@original_au_id" DeleteCommand="DELETE FROM [authors] WHERE [au_id] =
@original_au_id">
<SelectParameters>
<asp:ControlParameter ControlID="GridView1" Name="au_id"
PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="au_lname" Type="String" />
<asp:Parameter Name="au_fname" Type="String" />
<asp:Parameter Name="phone" Type="String" />
<asp:Parameter Name="address" Type="String" />
<asp:Parameter Name="city" Type="String" />
<asp:Parameter Name="state" Type="String" />
<asp:Parameter Name="zip" Type="String" />
<asp:Parameter Name="contract" Type="Boolean" />
<asp:Parameter Name="original_au_id" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
</td>
</tr>
</table>

--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Timm" wrote:
But how can the ControlID of the SelectParameter refer to a DropDownList in a
TemplateField of the DetailsView?

"Phillip Williams" wrote:
I have tried the following using SqlDataSource against the NorthWind database
and it worked fine:

<table>
<tr>
<td>Region</td>
<td>
<asp:DropDownList ID="ddlRegions" runat=server DataSourceID
="SqlRegions" DataTextField="RegionDescription"
DataValueField="RegionID" AutoPostBack="True"></asp:DropDownList>
<asp:SqlDataSource ID="SqlRegions" runat="server"
ConnectionString="<%$
ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT RegionID, RegionDescription FROM
Region">
</asp:SqlDataSource>
</td>
</tr>
<tr>
<td>Territory</td>
<td>
<asp:DropDownList ID="ddlTerritories2" runat=server DataSourceID
="SqlTerritories" DataTextField="TerritoryDescription"
DataValueField="TerritoryID"></asp:DropDownList>
<asp:SqlDataSource ID="SqlTerritories" runat="server"
ConnectionString="<%$
ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT TerritoryID, TerritoryDescription FROM
Territories WHERE (RegionID = @RegionID)">
<SelectParameters>
<asp:ControlParameter Name="RegionID" ControlID="ddlRegions"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>

</td>
</tr>

</table>
--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Timm" wrote:
Thanks Phillip, but I have tried something similar already and couldn't get
it to work, perhaps because my data sources are SqlDataSource (it might have
been helpful if I'd mentioned that in the first place!). Also note, DDL1 and
DDL2 are controls in TemplateFields within a DetailsView.

"Phillip Williams" wrote:

> Correction: Look in the Binding to a Visual Studio DataSet (instead of the
> Data Access layer) in the Quick Start tutorials that I gave its link.
>
> "Phillip Williams" wrote:
>
> > Yes you can. I just tested it on my PC. If you use Binding to DataAccess
> > Layer http://66.129.71.130/QuickStartv20/a...jects.aspx#dal
> >
> > Then you would have a parameterized query for selecting the items of the
> > second dropdown list. Something like this:
> >
> > <!-- this the first dropdown list --->
> > <asp:DropDownList ID="DropDownList1" runat="server"
> > DataSourceID="ObjectDataSource1" DataTextField="CategoryName"
> > DataValueField="CategoryID" AutoPostBack="True">
> > </asp:DropDownList>
> > <!-- this is the dependent dropdown list --->
> > <asp:DropDownList ID="DropDownList2" runat="server"
> > DataSourceID="ObjectDataSource2" DataTextField="Description"
> > DataValueField="CategoryID" AutoPostBack="True">
> > </asp:DropDownList>
> > <!-- this is the objectDataSource for the first dropdownlist --->
> > <asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
> > TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
> > SelectMethod="getMyFirstList"></asp:ObjectDataSource>
> > <!-- this is the objectDataSource for the second dropdownlist. It receives
> > a parameter from the first list --->
> > <asp:ObjectDataSource ID="ObjectDataSource2" runat="server"
> > TypeName="DataSetTableAdapters.CategoriesTableAdap ter"
> > SelectMethod="getMySecondList">
> > <SelectParameters>
> > <asp:ControlParameter ControlID="DropDownList1" Name="CategoryID"
> > PropertyName="SelectedValue"
> > Type="String" />
> > </SelectParameters>
> > </asp:ObjectDataSource>
> > --
> > HTH,
> > Phillip Williams
> > http://www.societopia.net
> > http://www.webswapp.com
> >
> >
> > "Timm" wrote:
> >
> > > I have an ASP.NET 2.0 page with two DropDownLists. I am using declarative
> > > data binding wherever possible and trying to minimize the use of code. The
> > > list of values in DropDownList DDL2 should be (filtered) dependent upon the
> > > selection in DDL1. I think this inevitably needs some code, but I'd be happy
> > > to be told otherwise!
> > > I have some code to handle OnSelectedIndexChanged for DDL1 that sets the
> > > FilterExpression associated with the DataSourceID of DDL2. My problem is that
> > > after the code executes, I get an InvalidOperationException error that says
> > > "Databinding methods such as Eval(), XPath(), and Bind() can only be used in
> > > the context of a databound control."
> > > How can I avoid this?

Nov 19 '05 #7
Hi Timm,

Here is how you make it work:
1- create 2 separate SqlDataSource objects; one for insert and one for edit,
e.g. instead of SqlProductType, place SqlProductTypeI and SqlProductTypeE
2- place the SqlDataSource objects within their respective templates, i.e.
the SqlProductTypeI within the Insert template and the SqlProductTypeE within
the Edit template
3- adjust the references accordingly

Here is my modification of your code that worked on my PC (I had to create
test tables to work with your data)

<asp:DetailsView ID="View1" runat="Server" DataSourceID="Sql1"
DataKeyNames="ID"
DefaultMode="ReadOnly" AutoGenerateRows="false"
EmptyDataText=" No record found "
AutoGenerateInsertButton="true" AutoGenerateEditButton="true">
<Fields>
<asp:BoundField DataField="ID" HeaderText="Ref."
SortExpression="ID" InsertVisible="false"
ReadOnly="true" />
<asp:TemplateField HeaderText="Product Ref.">
<InsertItemTemplate>
<asp:DropDownList ID="DDL1I" runat="server"
DataSourceID="SqlProductTypeI" DataTextField="ProductRef"
DataValueField="ProductRef"
AutoPostBack="true"
AppendDataBoundItems="true" />
<asp:SqlDataSource runat="server"
ID="SqlProductTypeI" SelectCommand="SELECT NULL AS [ProductRef] UNION SELECT
[ProductRef]
FROM [ProductType] Order by [ProductRef]"
ConnectionString="<%$ ConnectionStrings:Test %>">
</asp:SqlDataSource>
</InsertItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DDL1E" runat="server"
DataSourceID="SqlProductTypeE" DataTextField="ProductRef"
DataValueField="ProductRef"
AutoPostBack="true"
AppendDataBoundItems="true" />
<asp:SqlDataSource runat="server"
ID="SqlProductTypeE" SelectCommand="SELECT NULL AS [ProductRef] UNION SELECT
[ProductRef]
FROM [ProductType] Order by [ProductRef]"
ConnectionString="<%$ ConnectionStrings:Test %>">
</asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="ProductRef" runat="Server"
Text='<%# Bind("ProductRef") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Dependent Type">
<InsertItemTemplate>
<asp:DropDownList ID="DDL2I" runat="server"
DataSourceID="SqlDependentTypeI" DataTextField="ID"
DataValueField="ID" />
<asp:SqlDataSource runat="server"
ID="SqlDependentTypeI" SelectCommand="SELECT NULL AS [ProductRef], '' AS [ID]
UNION SELECT
[ProductRef], [ID] FROM [DependentType]
WHERE [ProductRef]=@ProductRef" ConnectionString="<%$ ConnectionStrings:Test
%>">
<SelectParameters>
<asp:ControlParameter ControlID="DDL1I"
Name="ProductRef" PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</InsertItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DDL2E" runat="server"
DataSourceID="SqlDependentTypeE" DataTextField="ID"
DataValueField="ID" />
<asp:SqlDataSource runat="server"
ID="SqlDependentTypeE" SelectCommand="SELECT NULL AS [ProductRef], '' AS [ID]
UNION SELECT
[ProductRef], [ID] FROM [DependentType]
WHERE [ProductRef]=@ProductRef" ConnectionString="<%$ ConnectionStrings:Test
%>">
<SelectParameters>
<asp:ControlParameter ControlID="DDL1E"
Name="ProductRef" PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="DependentType" runat="Server"
Text='<%# Bind("DependentType") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DependentDetails"
HeaderText="Dependent Details" SortExpression="DependentDetails" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource runat="server" ID="Sql1"
SelectCommand="SELECT [ID], [ProductRef], [DependentType],
[DependentDetails] FROM [MainTable] ORDER BY [ID] DESC"
UpdateCommand="UPDATE [MainTable] SET [ProductRef]=@ProductRef,
[DependentType]=@DependentType, [DependentDetails]=@DependentDetails WHERE
[ID] = @Original_ID"
InsertCommand="INSERT INTO [MainTable] ([ProductRef],
[DependentType], [DependentDetails]) SELECT @ProductRef, @DependentType,
@DependentDetails"
ConnectionString="<%$ ConnectionStrings:Test %>"
OldValuesParameterFormatString="Original_{0}">
<UpdateParameters>
<asp:Parameter Name="ID" Type="Int32" />
<asp:Parameter Name="ProductRef"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentType"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentDetails"
ConvertEmptyStringToNull="true" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="ProductRef"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentType"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentDetails"
ConvertEmptyStringToNull="true" />
</InsertParameters>
</asp:SqlDataSource>

--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Timm" wrote:
Many thanks again for your time and assistance Phillip. Please find below a
simplified version of my page, as requested. Your recommendation for a
ControlParameter based solution would be better than this one (based on
SelectedIndexChanged), but I still can't find a way to reference DDL1I or
DDL1E in the ControlParameter.

<%@ Page Language="VB" AutoEventWireup="false" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server"><title>Dependent DropDownLists</title></head>
<script runat="server" >
Protected Sub ProductRef_SelectedIndexChanged(ByVal sender As Object,
ByVal e As System.EventArgs)
SqlProductType.FilterExpression = "[ProductRef] IS NULL OR
[ProductRef]='" & sender.SelectedValue.ToString & "'"
End Sub
</script>
<body>
<form id="form1" runat="server">
<asp:DetailsView ID="View1" Runat="Server" DataSourceID="Sql1"
DataKeyNames="ID" DefaultMode="ReadOnly" AutoGenerateRows="false"
EmptyDataText=" No record found " AutoGenerateInsertButton="true"
AutoGenerateEditButton="true" >
<Fields>
<asp:BoundField DataField="ID" HeaderText="Ref."
SortExpression="ID" InsertVisible="false" ReadOnly="true" />
<asp:TemplateField HeaderText="Product Ref." >
<InsertItemTemplate>
<asp:DropDownList ID="DDL1I" Runat="server"
DataSourceID="SqlProductType" DataTextField="ProductRef"
DataValueField="ProductRef" SelectedValue='<%# Bind("ProductRef") %>'
OnSelectedIndexChanged="ProductRef_SelectedIndexCh anged"
AutoPostBack="true" AppendDataBoundItems="true" />
</InsertItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DDL1E" Runat="server"
DataSourceID="SqlProductType" DataTextField="ProductRef"
DataValueField="ProductRef" SelectedValue='<%# Bind("ProductRef") %>'
OnSelectedIndexChanged="ProductRef_SelectedIndexCh anged"
AutoPostBack="true" AppendDataBoundItems="true" />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="ProductRef" Runat="Server" Text='<%# Bind("ProductRef")
%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Dependent Type" >
<InsertItemTemplate>
<asp:DropDownList ID="DDL2I" Runat="server"
DataSourceID="SqlDependentType" DataTextField="ID" DataValueField="ID"
SelectedValue='<%# Bind("DependentType") %>' />
</InsertItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DDL2E" Runat="server"
DataSourceID="SqlDependentType" DataTextField="ID" DataValueField="ID"
SelectedValue='<%# Bind("DependentType") %>' />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="DependentType" Runat="Server" Text='<%#
Bind("DependentType") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DependentDetails"
HeaderText="Dependent Details" SortExpression="DependentDetails" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource Runat="server" ID="Sql1"
SelectCommand="SELECT [ID], [ProductRef], [DependentType],
[DependentDetails] FROM [MainTable] ORDER BY [ID] DESC"
UpdateCommand="UPDATE [MainTable] SET [ProductRef]=@ProductRef,
[DependentType]=@DependentType, [DependentDetails]=@DependentDetails WHERE
[ID] = @Original_ID"
InsertCommand="INSERT INTO [MainTable] ([ProductRef],
[DependentType], [DependentDetails]) SELECT @ProductRef, @DependentType,
@DependentDetails"
ConnectionString="<%$ ConnectionStrings:Test %>"
OldValuesParameterFormatString="Original_{0}" >
<UpdateParameters>
<asp:Parameter Name="ID" Type="Int32" />
<asp:Parameter Name="ProductRef" ConvertEmptyStringToNull="true"
/>
<asp:Parameter Name="DependentType"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentDetails"
ConvertEmptyStringToNull="true" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="ProductRef" ConvertEmptyStringToNull="true"
/>
<asp:Parameter Name="DependentType"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentDetails"
ConvertEmptyStringToNull="true" />
</InsertParameters>
</asp:SqlDataSource>
<asp:SqlDataSource Runat="server" ID="SqlProductType"
SelectCommand="SELECT NULL AS [ProductRef] UNION SELECT [ProductRef]
FROM [ProductType] ORDER BY [ProductRef]"
ConnectionString="<%$ ConnectionStrings:Test %>">
</asp:SqlDataSource>
<asp:SqlDataSource Runat="server" ID="SqlDependentType"
SelectCommand="SELECT NULL AS [ProductRef], '' AS [ID] UNION SELECT
[ProductRef], [ID] FROM [DependentType] ORDER BY [ProductRef]"
ConnectionString="<%$ ConnectionStrings:Test %>">
</asp:SqlDataSource>
</form>
</body>
</html>
"Phillip Williams" wrote:
Hi Timm,

I have placed the same code inside this sample of a DetailsView from the
Quickstart tutorials
http://66.129.71.130/QuickStartv20/u...lsEdit_cs.aspx
and it still worked. Can you post the code the you have not working?

Here it is the complete code that I tried:
<b>Choose a state:</b>
<asp:DropDownList ID="DropDownList1" DataSourceID="SqlDataSource2"
AutoPostBack="true"
DataTextField="state" runat="server"
OnSelectedIndexChanged="DropDownList1_SelectedInde xChanged" />
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
SelectCommand="SELECT DISTINCT [state] FROM [authors]"
ConnectionString="<%$ ConnectionStrings:Pubs %>" />
<br />
<br />
<table>
<tr>
<td valign="top">
<asp:GridView ID="GridView1" AllowSorting="True"
AllowPaging="True" runat="server"
DataSourceID="SqlDataSource1" DataKeyNames="au_id"
AutoGenerateColumns="False" Width="427px"
OnSelectedIndexChanged="GridView1_SelectedIndexCha nged"
OnSorted="GridView1_Sorted" OnPageIndexChanged="GridView1_PageIndexChanged">
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:BoundField DataField="au_id" HeaderText="au_id"
ReadOnly="True" SortExpression="au_id" />
<asp:BoundField DataField="au_lname" HeaderText="au_lname"
SortExpression="au_lname" />
<asp:BoundField DataField="au_fname" HeaderText="au_fname"
SortExpression="au_fname" />
<asp:BoundField DataField="state" HeaderText="state"
SortExpression="state" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
SelectCommand="SELECT [au_id], [au_lname], [au_fname], [state] FROM [authors]
WHERE ([state] = @state)"
ConnectionString="<%$ ConnectionStrings:Pubs %>">
<SelectParameters>
<asp:ControlParameter ControlID="DropDownList1" Name="state"
PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</td>
<td valign="top">
<asp:DetailsView AutoGenerateRows="False" DataKeyNames="au_id"
OnItemUpdated="DetailsView1_ItemUpdated" DataSourceID="SqlDataSource3"
HeaderText="Author Details" ID="DetailsView1" runat="server"
Width="275px">
<Fields>
<asp:BoundField DataField="au_id" HeaderText="au_id"
ReadOnly="True" SortExpression="au_id" />
<asp:BoundField DataField="au_lname" HeaderText="au_lname"
SortExpression="au_lname" />
<asp:BoundField DataField="au_fname" HeaderText="au_fname"
SortExpression="au_fname" />
<asp:BoundField DataField="phone" HeaderText="phone"
SortExpression="phone" />
<asp:BoundField DataField="address" HeaderText="address"
SortExpression="address" />
<asp:BoundField DataField="city" HeaderText="city"
SortExpression="city" />
<asp:BoundField DataField="state" HeaderText="state"
SortExpression="state" />
<asp:BoundField DataField="zip" HeaderText="zip"
SortExpression="zip" />
<asp:TemplateField >
<ItemTemplate>
<asp:Label runat=server ID="lblRegion" Text='<%#
Eval("City") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate >
<table>
<tr>
<td>Region</td>
<td>
<asp:DropDownList ID="ddlRegions" runat=server
DataSourceID ="SqlRegions" DataTextField="RegionDescription"
DataValueField="RegionID"
AutoPostBack="True"></asp:DropDownList>
<asp:SqlDataSource ID="SqlRegions" runat="server"
ConnectionString="<%$
ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT RegionID,
RegionDescription FROM Region">
</asp:SqlDataSource>
</td>
</tr>
<tr>
<td>Territory</td>
<td>
<asp:DropDownList ID="ddlTerritories2"
runat=server DataSourceID ="SqlTerritories"
DataTextField="TerritoryDescription"
DataValueField="TerritoryID"></asp:DropDownList>
<asp:SqlDataSource ID="SqlTerritories"
runat="server"
ConnectionString="<%$
ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT TerritoryID,
TerritoryDescription FROM Territories WHERE (RegionID = @RegionID)">
<SelectParameters>
<asp:ControlParameter Name="RegionID"
ControlID="ddlRegions" PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>

</td>
</tr>

</table>
</EditItemTemplate>
</asp:TemplateField>
<asp:CheckBoxField DataField="contract" HeaderText="contract"
SortExpression="contract" />
<asp:CommandField ShowEditButton="True" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="SqlDataSource3" runat="server"
ConnectionString="<%$ ConnectionStrings:Pubs %>"
SelectCommand="SELECT [au_id], [au_lname], [au_fname], [phone],
[address], [city], [state], [zip], [contract] FROM [authors] WHERE ([au_id] =
@au_id)"
UpdateCommand="UPDATE [authors] SET [au_lname] = @au_lname,
[au_fname] = @au_fname, [phone] = @phone, [address] = @address, [city] =
@city, [state] = @state, [zip] = @zip, [contract] = @contract WHERE [au_id] =
@original_au_id" DeleteCommand="DELETE FROM [authors] WHERE [au_id] =
@original_au_id">
<SelectParameters>
<asp:ControlParameter ControlID="GridView1" Name="au_id"
PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="au_lname" Type="String" />
<asp:Parameter Name="au_fname" Type="String" />
<asp:Parameter Name="phone" Type="String" />
<asp:Parameter Name="address" Type="String" />
<asp:Parameter Name="city" Type="String" />
<asp:Parameter Name="state" Type="String" />
<asp:Parameter Name="zip" Type="String" />
<asp:Parameter Name="contract" Type="Boolean" />
<asp:Parameter Name="original_au_id" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
</td>
</tr>
</table>

--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Timm" wrote:
But how can the ControlID of the SelectParameter refer to a DropDownList in a
TemplateField of the DetailsView?

"Phillip Williams" wrote:

> I have tried the following using SqlDataSource against the NorthWind database
> and it worked fine:
>
> <table>
> <tr>
> <td>Region</td>
> <td>
> <asp:DropDownList ID="ddlRegions" runat=server DataSourceID
> ="SqlRegions" DataTextField="RegionDescription"
> DataValueField="RegionID" AutoPostBack="True"></asp:DropDownList>
> <asp:SqlDataSource ID="SqlRegions" runat="server"
> ConnectionString="<%$
> ConnectionStrings:NorthwindConnectionString %>"
> SelectCommand="SELECT RegionID, RegionDescription FROM
> Region">
> </asp:SqlDataSource>
> </td>
> </tr>
> <tr>
> <td>Territory</td>

Nov 19 '05 #8
Hi Phillip.

Your code is a major step forward, thanks again. The binding (of the
SelectedValue) for the DropDownLists was missing, so I have added that. I've
also improved the NULL handling (which was implemented as UNIONs in the SQL
select statements to work around limitations of ASP.NET Beta 2) now that
AppendDataBoundItems works properly, see the revised code below.

Editing the dependent DropDownList (DDL2E) works well. However, attempts to
change the product (DDL1I) fail, even if the same dependent value is valid
for both old and new products. The error reported is similar to previously:

Server Error in '/TestWeb' Application.
--------------------------------------------------------------------------------

Databinding methods such as Eval(), XPath(), and Bind() can only be used in
the context of a databound control.
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information about
the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Databinding methods
such as Eval(), XPath(), and Bind() can only be used in the context of a
databound control.

A similar error is reported when inserting data also.

<asp:DetailsView ID="View1" runat="Server" DataSourceID="Sql1"
DataKeyNames="ID"
DefaultMode="ReadOnly" AutoGenerateRows="false" EmptyDataText="
No record found "
AutoGenerateInsertButton="true" AutoGenerateEditButton="true"
AllowPaging="true" >
<Fields>
<asp:BoundField DataField="ID" HeaderText="Ref."
SortExpression="ID" InsertVisible="false"
ReadOnly="true" />
<asp:TemplateField HeaderText="Product Ref.">
<InsertItemTemplate>
<asp:DropDownList ID="DDL1I" runat="server"
DataSourceID="SqlProductTypeI" DataTextField="ProductRef" SelectedValue='<%#
Bind("ProductRef") %>'
DataValueField="ProductRef" AutoPostBack="true"
AppendDataBoundItems="true"><asp:ListItem></asp:ListItem></asp:DropDownList>
<asp:SqlDataSource runat="server"
ID="SqlProductTypeI"
SelectCommand="SELECT [ProductRef] FROM
[ProductType] Order by [ProductRef]"
ConnectionString="<%$ ConnectionStrings:Test %>">
</asp:SqlDataSource>
</InsertItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DDL1E" runat="server"
DataSourceID="SqlProductTypeE" DataTextField="ProductRef" SelectedValue='<%#
Bind("ProductRef") %>'
DataValueField="ProductRef" AutoPostBack="true"
AppendDataBoundItems="true"><asp:ListItem></asp:ListItem></asp:DropDownList>
<asp:SqlDataSource runat="server"
ID="SqlProductTypeE"
SelectCommand="SELECT [ProductRef] FROM
[ProductType] Order by [ProductRef]"
ConnectionString="<%$ ConnectionStrings:Test %>">
</asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="ProductRef" runat="Server" Text='<%#
Bind("ProductRef") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Dependent Type">
<InsertItemTemplate>
<asp:DropDownList ID="DDL2I" runat="server"
DataSourceID="SqlDependentTypeI" DataTextField="ID" SelectedValue='<%#
Bind("DependentType") %>'
DataValueField="ID"
AppendDataBoundItems="true"><asp:ListItem></asp:ListItem></asp:DropDownList>
<asp:SqlDataSource runat="server"
ID="SqlDependentTypeI"
SelectCommand="SELECT [ID] FROM [DependentType]
WHERE [ProductRef]=@ProductRef"
ConnectionString="<%$ ConnectionStrings:Test %>">
<SelectParameters>
<asp:ControlParameter ControlID="DDL1I"
Name="ProductRef" PropertyName="SelectedValue" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</InsertItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DDL2E" runat="server"
DataSourceID="SqlDependentTypeE" DataTextField="ID" SelectedValue='<%#
Bind("DependentType") %>'
DataValueField="ID"
AppendDataBoundItems="true"><asp:ListItem></asp:ListItem></asp:DropDownList>
<asp:SqlDataSource runat="server"
ID="SqlDependentTypeE"
SelectCommand="SELECT [ID] FROM [DependentType]
WHERE [ProductRef]=@ProductRef"
ConnectionString="<%$ ConnectionStrings:Test %>">
<SelectParameters>
<asp:ControlParameter ControlID="DDL1E"
Name="ProductRef" PropertyName="SelectedValue" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="DependentType" runat="Server"
Text='<%# Bind("DependentType") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DependentDetails"
HeaderText="Dependent Details" SortExpression="DependentDetails" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource runat="server" ID="Sql1"
SelectCommand="SELECT [ID], [ProductRef], [DependentType],
[DependentDetails] FROM [MainTable] ORDER BY [ID] DESC"
UpdateCommand="UPDATE [MainTable] SET [ProductRef]=@ProductRef,
[DependentType]=@DependentType, [DependentDetails]=@DependentDetails WHERE
[ID] = @Original_ID"
InsertCommand="INSERT INTO [MainTable] ([ProductRef],
[DependentType], [DependentDetails]) SELECT @ProductRef, @DependentType,
@DependentDetails"
ConnectionString="<%$ ConnectionStrings:Test %>"
OldValuesParameterFormatString="Original_{0}">
<UpdateParameters>
<asp:Parameter Name="ID" Type="Int32" />
<asp:Parameter Name="ProductRef"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentType"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentDetails"
ConvertEmptyStringToNull="true" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="ProductRef"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentType"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentDetails"
ConvertEmptyStringToNull="true" />
</InsertParameters>
</asp:SqlDataSource>

Nov 19 '05 #9
Hi Timm,

The challenge in what you are trying to do is that you are using 2-way
databinding to extract the selectevalue of the dropdownlist from the template
in order to pass it to the datasource. However since the second dropdownlist
was databound as OnSelectedindexchanged event of the first dropdownlist, the
template was not databound, only the dropdownlist. This was the reason the
exception “Databinding methods such as Eval(), XPath(), and Bind() can only
be used in the context of a databound control” was thrown.

Avoiding that error does not solve the problem though. To avoid the error,
you would have to execute the View1.DataBind() method OnSelectedIndexChanged
event handling for the first list. This eliminates the error that you got
but it creates 2 other problems:

a. by databinding you lose the value of the first dropdownlist which you
just updated. To avoid this you could try to update (in the codebehind)
first the View before you do the databinding. (but then that defeats the
purpose of doing every thing declaratively as you originally wanted)
b. Even though…if you update first, then the second challenge you will have
is that you filtered the second list based on the selection of the first then
attempted to bind it 2-way using the value that existed in the datasource
(this value might not match any of the values that exist now on the list) and
therefore an excpetion would be thrown that the value could not be found.
This happens because the dependent dropdownlist is databound upon changing
the first dropdownlist and before the user had a chance to change its value.

In summary I think that the 2-way databinding on the dependent dropdownlist
does not make business sense. To solve the problem,
1) remove the 2-way databinding on the dependent dropdownlists,
2) Update the individual table record OnSelectedIndexChanged event handling
of the dependent dropdownlists using customized code.

--
HTH,
Phillip Williams
http://www.societopia.net
http://www.webswapp.com
"Timm" wrote:
Hi Phillip.

Your code is a major step forward, thanks again. The binding (of the
SelectedValue) for the DropDownLists was missing, so I have added that. I've
also improved the NULL handling (which was implemented as UNIONs in the SQL
select statements to work around limitations of ASP.NET Beta 2) now that
AppendDataBoundItems works properly, see the revised code below.

Editing the dependent DropDownList (DDL2E) works well. However, attempts to
change the product (DDL1I) fail, even if the same dependent value is valid
for both old and new products. The error reported is similar to previously:

Server Error in '/TestWeb' Application.
--------------------------------------------------------------------------------

Databinding methods such as Eval(), XPath(), and Bind() can only be used in
the context of a databound control.
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information about
the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Databinding methods
such as Eval(), XPath(), and Bind() can only be used in the context of a
databound control.

A similar error is reported when inserting data also.

<asp:DetailsView ID="View1" runat="Server" DataSourceID="Sql1"
DataKeyNames="ID"
DefaultMode="ReadOnly" AutoGenerateRows="false" EmptyDataText="
No record found "
AutoGenerateInsertButton="true" AutoGenerateEditButton="true"
AllowPaging="true" >
<Fields>
<asp:BoundField DataField="ID" HeaderText="Ref."
SortExpression="ID" InsertVisible="false"
ReadOnly="true" />
<asp:TemplateField HeaderText="Product Ref.">
<InsertItemTemplate>
<asp:DropDownList ID="DDL1I" runat="server"
DataSourceID="SqlProductTypeI" DataTextField="ProductRef" SelectedValue='<%#
Bind("ProductRef") %>'
DataValueField="ProductRef" AutoPostBack="true"
AppendDataBoundItems="true"><asp:ListItem></asp:ListItem></asp:DropDownList>
<asp:SqlDataSource runat="server"
ID="SqlProductTypeI"
SelectCommand="SELECT [ProductRef] FROM
[ProductType] Order by [ProductRef]"
ConnectionString="<%$ ConnectionStrings:Test %>">
</asp:SqlDataSource>
</InsertItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DDL1E" runat="server"
DataSourceID="SqlProductTypeE" DataTextField="ProductRef" SelectedValue='<%#
Bind("ProductRef") %>'
DataValueField="ProductRef" AutoPostBack="true"
AppendDataBoundItems="true"><asp:ListItem></asp:ListItem></asp:DropDownList>
<asp:SqlDataSource runat="server"
ID="SqlProductTypeE"
SelectCommand="SELECT [ProductRef] FROM
[ProductType] Order by [ProductRef]"
ConnectionString="<%$ ConnectionStrings:Test %>">
</asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="ProductRef" runat="Server" Text='<%#
Bind("ProductRef") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Dependent Type">
<InsertItemTemplate>
<asp:DropDownList ID="DDL2I" runat="server"
DataSourceID="SqlDependentTypeI" DataTextField="ID" SelectedValue='<%#
Bind("DependentType") %>'
DataValueField="ID"
AppendDataBoundItems="true"><asp:ListItem></asp:ListItem></asp:DropDownList>
<asp:SqlDataSource runat="server"
ID="SqlDependentTypeI"
SelectCommand="SELECT [ID] FROM [DependentType]
WHERE [ProductRef]=@ProductRef"
ConnectionString="<%$ ConnectionStrings:Test %>">
<SelectParameters>
<asp:ControlParameter ControlID="DDL1I"
Name="ProductRef" PropertyName="SelectedValue" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</InsertItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DDL2E" runat="server"
DataSourceID="SqlDependentTypeE" DataTextField="ID" SelectedValue='<%#
Bind("DependentType") %>'
DataValueField="ID"
AppendDataBoundItems="true"><asp:ListItem></asp:ListItem></asp:DropDownList>
<asp:SqlDataSource runat="server"
ID="SqlDependentTypeE"
SelectCommand="SELECT [ID] FROM [DependentType]
WHERE [ProductRef]=@ProductRef"
ConnectionString="<%$ ConnectionStrings:Test %>">
<SelectParameters>
<asp:ControlParameter ControlID="DDL1E"
Name="ProductRef" PropertyName="SelectedValue" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="DependentType" runat="Server"
Text='<%# Bind("DependentType") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DependentDetails"
HeaderText="Dependent Details" SortExpression="DependentDetails" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource runat="server" ID="Sql1"
SelectCommand="SELECT [ID], [ProductRef], [DependentType],
[DependentDetails] FROM [MainTable] ORDER BY [ID] DESC"
UpdateCommand="UPDATE [MainTable] SET [ProductRef]=@ProductRef,
[DependentType]=@DependentType, [DependentDetails]=@DependentDetails WHERE
[ID] = @Original_ID"
InsertCommand="INSERT INTO [MainTable] ([ProductRef],
[DependentType], [DependentDetails]) SELECT @ProductRef, @DependentType,
@DependentDetails"
ConnectionString="<%$ ConnectionStrings:Test %>"
OldValuesParameterFormatString="Original_{0}">
<UpdateParameters>
<asp:Parameter Name="ID" Type="Int32" />
<asp:Parameter Name="ProductRef"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentType"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentDetails"
ConvertEmptyStringToNull="true" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="ProductRef"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentType"
ConvertEmptyStringToNull="true" />
<asp:Parameter Name="DependentDetails"
ConvertEmptyStringToNull="true" />
</InsertParameters>
</asp:SqlDataSource>

Nov 19 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

108
by: Zooko O'Whielacronx | last post by:
I'm a fan of Greg Ewing's PyGUI . I used it to code a simple game for my son , and enjoyed it. Programming with wxPython feels like programming with a C++ tool that has been wrapped in Python....
33
by: Jacek Generowicz | last post by:
I would like to write a metaclass which would allow me to overload names in the definition of its instances, like this class Foo(object): __metaclass__ = OverloadingClass att = 1 att = 3
2
by: Marlene Harkcom | last post by:
I've got a datagrid with 5 bound columns in it as well as an edit/update/cancel column. I'm binding this to a dataset. One of the fields is always going to be one of three values. I want the...
0
by: theo | last post by:
Hello..I have a similar issue as yesterday but the situation has slightly changed so perhaps someone can shed some more light on the issue... Program flow - load file,extract xml text tags from...
3
by: Jim Bancroft | last post by:
Hi everyone, I'd like to put some DropDownLists in my DataGrid, populating each from a database query. I'm having a little trouble naming them based on the current record in the DataSet. For...
1
by: Paul-Andr Ct | last post by:
Hi, I've been playing with VBx and VB.NET for a while now but ... Let say in VB.Net, I've never understood how or which event I should use when I update one of two interdependent textboxes. ...
0
by: Mike | last post by:
I've a datagrid containing user's information which onselect displays a detailsview control in edit mode I've set-up two template fields to map to (country) and (region) these are dropdownlists...
0
by: Carlos | last post by:
Hi all, I just embedded a dropdownlist templatefield inside a gridview. When I look at the control in design mode, I see 5 dropdownlists, when I bind the data to the gridview, I only bind to 3...
3
by: RSH | last post by:
Hi, I am having this very bizarre occurance with 4 dropdown lists on my ASP .Net page. Each control has its own unique id. When the user selects a value from each of the dropdownlists it is...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Sept 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
0
by: lllomh | last post by:
How does React native implement an English player?
0
by: Mushico | last post by:
How to calculate date of retirement from date of birth
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.