By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,179 Members | 1,175 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,179 IT Pros & Developers. It's quick & easy.

Interdependent DropDownLists (with declarative data binding)

P: n/a
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
Share this Question
Share on Google+
9 Replies


P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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

P: n/a
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 discussion thread is closed

Replies have been disabled for this discussion.