トップ回答者
(ソースコードを書かなくても、htmlソースのみで、)ListViewに配置した2つのDropDownListの連携は出来ますか?

質問
-
質問:(ソースコードを書かなくても、htmlソースのみで、)ListViewに配置した2つのDropDownListの連携は出来ますか?(htmlソースは下記参照ください。)
やろうとしている事:
2つのDropDownListを配置したListViewを使った、顧客マスターの登録において、
1.1つ目のDropDownListに部店マスターを繋げて、部店コードを選択させる。
2.2つ目のDropDownListには、繋げた扱者マスターの内、1で選択した部店の扱者コードのみを表示する。
問題:エラーが発生し、機能しない。(エラーは下記参照ください。)
なお、以前、「ListViewにDropDownListを組み込むには」を投稿しました。今回の質問は、機能的にはその延長線上にあります。開発環境:
OS: Windows10 Pro 64 bit
.NET Framework: 4.5.1(Visual Studio上、プロジェクトープロパティの「ターゲット フレームワーク」より).NET Framework: 4.7.2(レジストリ エディターより)
.NET Framework: 4.7.03190(「Microsoft Visual Studioのバージョン情報」より)
IIS: 10.0.17763.1
VIsual Studio: Professional 2017 Version 15.8.9
Microsoft SQL Server Express (64-bit): 13.0.4224.16 (日本語)
<<< htmlコード >>>><%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="reg_new_account_for_gaisai_for_question.WebForm1" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:ListView ID="ListView1" runat="server" DataKeyNames="ActNo" DataSourceID="SqlDataSource1" InsertItemPosition="LastItem"> <AlternatingItemTemplate> <tr style=""> <td> <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="削除" /> <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="編集" /> </td> <td> <asp:DynamicControl runat="server" DataField="BtnCD" Mode="ReadOnly" /> </td> <td> <asp:DynamicControl runat="server" DataField="AtkaiCD" Mode="ReadOnly" /> </td> <td> <asp:DynamicControl runat="server" DataField="ActNo" Mode="ReadOnly" /> </td> </tr> </AlternatingItemTemplate> <EditItemTemplate> <tr style=""> <td> <asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="更新" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="キャンセル" /> </td> <td> <asp:DynamicControl runat="server" DataField="BtnCD" Mode="Edit" /> </td> <td> <asp:DynamicControl runat="server" DataField="AtkaiCD" Mode="Edit" /> </td> <td> <asp:DynamicControl runat="server" DataField="ActNo" Mode="ReadOnly" /> </td> </tr> </EditItemTemplate> <EmptyDataTemplate> <table runat="server" style=""> <tr> <td>データは返されませんでした。</td> </tr> </table> </EmptyDataTemplate> <InsertItemTemplate> <tr style=""> <td> <asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="挿入" ValidationGroup="Insert" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="クリア" /> </td> <td> <asp:DynamicControl runat="server" DataField="BtnCD" Mode="Insert" ValidationGroup="Insert" /> </td> <td> <asp:DynamicControl runat="server" DataField="AtkaiCD" Mode="Insert" ValidationGroup="Insert" /> </td> <td> <asp:DynamicControl runat="server" DataField="ActNo" Mode="Insert" ValidationGroup="Insert" /> </td> </tr> </InsertItemTemplate> <ItemTemplate> <tr style=""> <td> <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="削除" /> <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="編集" /> </td> <td> <asp:DynamicControl runat="server" DataField="BtnCD" Mode="ReadOnly" /> </td> <td> <asp:DynamicControl runat="server" DataField="AtkaiCD" Mode="ReadOnly" /> </td> <td> <asp:DynamicControl runat="server" DataField="ActNo" Mode="ReadOnly" /> </td> </tr> </ItemTemplate> <LayoutTemplate> <table runat="server"> <tr runat="server"> <td runat="server"> <table id="itemPlaceholderContainer" runat="server" border="0" style=""> <tr runat="server" style=""> <th runat="server"></th> <th runat="server">BtnCD</th> <th runat="server">AtkaiCD</th> <th runat="server">ActNo</th> </tr> <tr id="itemPlaceholder" runat="server"> </tr> </table> </td> </tr> <tr runat="server"> <td runat="server" style=""> <asp:DataPager ID="DataPager1" runat="server"> <Fields> <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" ShowLastPageButton="True" /> </Fields> </asp:DataPager> </td> </tr> </table> </LayoutTemplate> <SelectedItemTemplate> <tr style=""> <td> <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="削除" /> <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="編集" /> </td> <td> <asp:DynamicControl runat="server" DataField="BtnCD" Mode="ReadOnly" /> </td> <td> <asp:DynamicControl runat="server" DataField="AtkaiCD" Mode="ReadOnly" /> </td> <td> <asp:DynamicControl runat="server" DataField="ActNo" Mode="ReadOnly" /> </td> </tr> </SelectedItemTemplate> </asp:ListView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConflictDetection="CompareAllValues" ConnectionString="<%$ ConnectionStrings:complianceConnectionString %>" DeleteCommand="DELETE FROM [acct_new] WHERE [ActNo] = @original_ActNo AND (([BtnCD] = @original_BtnCD) OR ([BtnCD] IS NULL AND @original_BtnCD IS NULL)) AND (([AtkaiCD] = @original_AtkaiCD) OR ([AtkaiCD] IS NULL AND @original_AtkaiCD IS NULL))" InsertCommand="INSERT INTO [acct_new] ([BtnCD], [AtkaiCD], [ActNo]) VALUES (@BtnCD, @AtkaiCD, @ActNo)" OldValuesParameterFormatString="original_{0}" SelectCommand="SELECT [BtnCD], [AtkaiCD], [ActNo] FROM [acct_new]" UpdateCommand="UPDATE [acct_new] SET [BtnCD] = @BtnCD, [AtkaiCD] = @AtkaiCD WHERE [ActNo] = @original_ActNo AND (([BtnCD] = @original_BtnCD) OR ([BtnCD] IS NULL AND @original_BtnCD IS NULL)) AND (([AtkaiCD] = @original_AtkaiCD) OR ([AtkaiCD] IS NULL AND @original_AtkaiCD IS NULL))"> <DeleteParameters> <asp:Parameter Name="original_ActNo" Type="String" /> <asp:Parameter Name="original_BtnCD" Type="String" /> <asp:Parameter Name="original_AtkaiCD" Type="String" /> </DeleteParameters> <InsertParameters> <asp:Parameter Name="BtnCD" Type="String" /> <asp:Parameter Name="AtkaiCD" Type="String" /> <asp:Parameter Name="ActNo" Type="String" /> </InsertParameters> <UpdateParameters> <asp:Parameter Name="BtnCD" Type="String" /> <asp:Parameter Name="AtkaiCD" Type="String" /> <asp:Parameter Name="original_ActNo" Type="String" /> <asp:Parameter Name="original_BtnCD" Type="String" /> <asp:Parameter Name="original_AtkaiCD" Type="String" /> </UpdateParameters> </asp:SqlDataSource> <asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:complianceConnectionString2 %>" SelectCommand="SELECT [BtnCD] FROM [butn]"></asp:SqlDataSource> <asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:complianceConnectionString3 %>" SelectCommand="SELECT [AtkaiCD] FROM [atsu] WHERE ([BtnCD] = @BtnCD)"> <SelectParameters> <asp:ControlParameter ControlID="BtnCDDropDownList" DefaultValue="001" Name="BtnCD" PropertyName="SelectedValue" Type="String" /> </SelectParameters> </asp:SqlDataSource> </div> </form> </body> </html>
<<< エラーメッセージ >>>
'/' アプリケーションでサーバー エラーが発生しました。 コントロール 'BtnCDDropDownList' は ControlParameter 'BtnCD' 内に見つかりませんでした。 説明: 現在の Web 要求を実行中に、ハンドルされていない例外が発生しました。エラーに関する詳細および例外の発生場所については、スタック トレースを参照してください。 例外の詳細: System.InvalidOperationException: コントロール 'BtnCDDropDownList' は ControlParameter 'BtnCD' 内に見つかりませんでした。 ソース エラー: 現在の Web 要求の実行中にハンドルされていない例外が生成されました。障害の原因および発生場所に関する情報については、下の例外スタック トレースを使って確認できます。 スタック トレース: [InvalidOperationException: コントロール 'BtnCDDropDownList' は ControlParameter 'BtnCD' 内に見つかりませんでした。] System.Web.UI.WebControls.ControlParameter.Evaluate(HttpContext context, Control control) +2751868 System.Web.UI.WebControls.Parameter.UpdateValue(HttpContext context, Control control) +50 System.Web.UI.WebControls.ParameterCollection.UpdateValues(HttpContext context, Control control) +101 System.Web.UI.WebControls.SqlDataSource.LoadCompleteEventHandler(Object sender, EventArgs e) +46 System.EventHandler.Invoke(Object sender, EventArgs e) +0 System.Web.UI.Page.OnLoadComplete(EventArgs e) +9883722 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +776 バージョン情報: Microsoft .NET Framework バージョン:4.0.30319; ASP.NET バージョン:4.7.3429.0
参照したWebサイト:
・「DropDownlistのSelectIndexChangesイベントタイミングについて」(DropDownListが直貼りの様なので、事情が異なり、まねしたところ、下のエラーが発生しました。)
・「2つのDropDownListの連携について」(記事中のリンク先「DetailsViewの中に、多段階のDropDownListを配置できない」のページ上の
『@ITのほうでも同じ質問があがったのでなんとか実現する方法がないか試してみました。
少しプログラムを記述することで実装できました。』(http://dotnetfan.org/blogs/dotnetfanblog/articles/737.aspx)のリンク先に該当の記事はありませんでした。)
・「FormViewの編集モードで部署を変更したら所属員のドロップダウンリストを変更したい」(ページ内のリンク「Demo for 2-way databinding cascading lists within a FormView」はセキュリティソフトに阻まれて直接アクセス出来なかったため、タイトルの「Demo for 2-way databinding cascading lists within a FormView」によるGoogle検索結果からアクセスし、記事は読みましたが、ソースファイルのダウンロードが再度セキュリティソフトに阻まれた為、安全策を取り、ソースファイルのダウンロードは断念しました。)
下のWebサイトを見ると、やはり、ソースコードを書かないと実現できないのでしょうか?
・「2つのDropDownListの連動」
・「GridView内にある二つのDropDownListを連動させたい」以上、よろしくお願いします。
回答
-
上に紹介した DetailsView の例(下に URL 再掲します)と同様な連動 DropDownList を ListView 内で試してみましたが、やはりコードビハインドにコードを書かないと動きませんでした。
DetailsView 中の連動 DropDownList
http://surferonwww.info/BlogEngine/post/2010/12/04/Dual-DropDownLists-in-DetailsView.aspxコードを書かずに済むようにするには、2 つめの DropDownList に SelectedValue='<%# Bind("ProductID") %>' と設定する必要があります。
そうすると、初期画面では 2 つの DropDownList に期待通り選択された項目が表示されますが、そこから 1 つ目の DropDownList のアイテムの選択を変更すると "System.InvalidOperationException: Eval()、XPath()、および Bind() のようなデータバインド メソッドは、データバインドされたコントロールのコンテキストでのみ使用することができます。" という DetailsView の場合と同じエラーになります。
という訳で、
> (ソースコードを書かなくても、htmlソースのみで、)ListViewに配置した2つのDropDownListの連携は出来ますか?
に対する答えは、私が試した限りですが、できませんということになりました。
- 編集済み SurferOnWww 2019年12月1日 6:23 訂正
- 回答としてマーク Herokey 2019年12月2日 1:43
-
ListView を使った例をアップしておきます。CategoryName 列のドロップダウンリストから特定の Category を選ぶと、その Category に属する Products が ProductName 列のドロップダウンリストに表示されるようにしています。
基本的には以下の記事の DetailsView 例を ListView で書き直したものです。
DetailsView 中の連動 DropDownList
http://surferonwww.info/BlogEngine/post/2010/12/04/Dual-DropDownLists-in-DetailsView.aspxちなみに、環境は Windows 10 Pro 64-bit, IIS10, .NET 4.6.1, SQL Server 2008 Express, Visual Studio Community 2015 のテンプレートで作った Web サイトプロジェクトです。
.aspc.cs(コードビハインド)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; public partial class _0086CascadingDropDownListsInListView : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } // ListView.ItemEditing イベントのハンドラで編集する項目の Index は取得できるが // それを使って ItemDataBound イベントのハンドラ内で項目を特定するのが問題。 // 以下のようにするのが分かりやすくてよさそう。(全項目で探すのに抵抗があるが) // ちなみに ItemEditing イベント発生時点では FindControl で取得できないので注意。 protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e) { if (e.Item.ItemType == ListViewItemType.DataItem) { ListViewDataItem item = (ListViewDataItem)e.Item; DropDownList ddl = (DropDownList)item.FindControl("DropDownList2"); if (ddl != null) { ddl.SelectedValue = ((DataRowView)item.DataItem)["ProductID"].ToString(); } } } protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e) { Control ctrl = ((ListView)sender).Items[e.ItemIndex].FindControl("DropDownList2"); if (ctrl != null) { e.NewValues["ProductID"] = ((DropDownList)ctrl).SelectedValue; } else { e.Cancel = true; } } protected void ListView1_ItemInserting(object sender, ListViewInsertEventArgs e) { DropDownList ddlCategory = (DropDownList)e.Item.FindControl("DropDownList3"); DropDownList ddlProduct = (DropDownList)e.Item.FindControl("DropDownList4"); if (ddlCategory != null && ddlProduct != null) { e.Values["CategoryID"] = ddlCategory.SelectedValue; e.Values["ProductID"] = ddlProduct.SelectedValue; } else { e.Cancel = true; } } }
.aspx
Visual Studio のテンプレートで自動生成されるマスターページを使用(即ち、ScriptManager によるスクリプトマッピングを利用)。
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="0086CascadingDropDownListsInListView.aspx.cs" Inherits="_0086CascadingDropDownListsInListView" %> <asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" Runat="Server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server"> <%--ListView 用--%> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" DeleteCommand="DELETE FROM [Sales] WHERE ([ID] = @ID)" InsertCommand="INSERT INTO [Sales] ([CategoryID], [ProductID]) VALUES (@CategoryID, @ProductID)" SelectCommand= "SELECT s.ID, s.CategoryID, s.ProductID, c.CategoryName, p.ProductName FROM Sales AS s INNER JOIN Categories AS c ON s.CategoryID = c.CategoryID INNER JOIN Products AS p ON s.ProductID = p.ProductID" UpdateCommand="UPDATE [Sales] SET [CategoryID] = @CategoryID, [ProductID] = @ProductID WHERE ([ID] = @ID)"> <DeleteParameters> <asp:Parameter Name="ID" Type="Int32" /> </DeleteParameters> <InsertParameters> <asp:Parameter Name="CategoryID" Type="Int32" /> <asp:Parameter Name="ProductID" Type="Int32" /> </InsertParameters> <UpdateParameters> <asp:Parameter Name="CategoryID" Type="Int32" /> <asp:Parameter Name="ProductID" Type="Int32" /> <asp:Parameter Name="ID" Type="Int32" /> </UpdateParameters> </asp:SqlDataSource> <asp:ListView ID="ListView1" runat="server" DataKeyNames="ID" DataSourceID="SqlDataSource1" InsertItemPosition="LastItem" OnItemDataBound="ListView1_ItemDataBound" OnItemUpdating="ListView1_ItemUpdating" OnItemInserting="ListView1_ItemInserting"> <EditItemTemplate> <tr style=""> <td> <asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="更新" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="キャンセル" /> </td> <td> <asp:Label ID="IDLabel1" runat="server" Text='<%# Eval("ID") %>' /> </td> <td> <asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]"> </asp:SqlDataSource> <asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="SqlDataSource2" DataTextField="CategoryName" DataValueField="CategoryID" AutoPostBack="True" SelectedValue='<%# Bind("CategoryID") %>'> </asp:DropDownList> </td> <td> <asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" SelectCommand="SELECT [ProductID], [ProductName] FROM [Products] WHERE ([CategoryID] = @CategoryID)"> <SelectParameters> <asp:ControlParameter ControlID="DropDownList1" Name="CategoryID" PropertyName="SelectedValue" Type="Int32" /> </SelectParameters> </asp:SqlDataSource> <%-- SelectedValue='<%# Bind("ProductID") %>' と設定するのは NG --%> <asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="SqlDataSource3" DataTextField="ProductName" DataValueField="ProductID"> </asp:DropDownList> </td> </tr> </EditItemTemplate> <EmptyDataTemplate> <table runat="server" style=""> <tr> <td>データは返されませんでした。</td> </tr> </table> </EmptyDataTemplate> <InsertItemTemplate> <tr style=""> <td> <asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="挿入" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="クリア" /> </td> <td> </td> <td> <asp:SqlDataSource ID="SqlDataSource4" runat="server" ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]"> </asp:SqlDataSource> <asp:DropDownList ID="DropDownList3" runat="server" DataSourceID="SqlDataSource4" DataTextField="CategoryName" DataValueField="CategoryID" AutoPostBack="True"> </asp:DropDownList> </td> <td> <asp:SqlDataSource ID="SqlDataSource5" runat="server" ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" SelectCommand="SELECT [ProductID], [ProductName] FROM [Products] WHERE ([CategoryID] = @CategoryID)"> <SelectParameters> <asp:ControlParameter ControlID="DropDownList3" Name="CategoryID" PropertyName="SelectedValue" Type="Int32" /> </SelectParameters> </asp:SqlDataSource> <asp:DropDownList ID="DropDownList4" runat="server" DataSourceID="SqlDataSource5" DataTextField="ProductName" DataValueField="ProductID"> </asp:DropDownList> </td> </tr> </InsertItemTemplate> <ItemTemplate> <tr style=""> <td> <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="削除" /> <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="編集" /> </td> <td> <asp:Label ID="IDLabel" runat="server" Text='<%# Eval("ID") %>' /> </td> <td> <asp:Label ID="CategoryNameLabel" runat="server" Text='<%# Eval("CategoryName") %>' /> </td> <td> <asp:Label ID="ProductNameLabel" runat="server" Text='<%# Eval("ProductName") %>' /> </td> </tr> </ItemTemplate> <LayoutTemplate> <table runat="server"> <tr runat="server"> <td runat="server"> <table id="itemPlaceholderContainer" runat="server" border="0" style=""> <tr runat="server" style=""> <th runat="server"></th> <th runat="server">ID</th> <th runat="server">CategoryName</th> <th runat="server">ProductName</th> </tr> <tr id="itemPlaceholder" runat="server"> </tr> </table> </td> </tr> <tr runat="server"> <td runat="server" style=""></td> </tr> </table> </LayoutTemplate> </asp:ListView> </asp:Content>
- 回答としてマーク Herokey 2019年12月3日 7:52
すべての返信
-
上の私のレスで、
> DetailsView の場合ですが、その中の配置した連動 DropDownList が aspx のコードだけでは動かなかったことがありました。今出先なので、後で調べてその情報を書きますね。
と書きましたが、自分のブログに記録がありましたので、その URL を以下に書いておきます。
DetailsView 中の連動 DropDownList
http://surferonwww.info/BlogEngine/post/2010/12/04/Dual-DropDownLists-in-DetailsView.aspxただ、質問者さんのソースを見るとそういう話ではなさそうですね。DropDownList はどこにも見当たりません。
エラーの原因は、
<asp:ControlParameter ControlID="BtnCDDropDownList" ...
となっているものの、BtnCDDropDownList がどこにもないということのようです。根本的に何か変ですよ。
-
上に紹介した DetailsView の例(下に URL 再掲します)と同様な連動 DropDownList を ListView 内で試してみましたが、やはりコードビハインドにコードを書かないと動きませんでした。
DetailsView 中の連動 DropDownList
http://surferonwww.info/BlogEngine/post/2010/12/04/Dual-DropDownLists-in-DetailsView.aspxコードを書かずに済むようにするには、2 つめの DropDownList に SelectedValue='<%# Bind("ProductID") %>' と設定する必要があります。
そうすると、初期画面では 2 つの DropDownList に期待通り選択された項目が表示されますが、そこから 1 つ目の DropDownList のアイテムの選択を変更すると "System.InvalidOperationException: Eval()、XPath()、および Bind() のようなデータバインド メソッドは、データバインドされたコントロールのコンテキストでのみ使用することができます。" という DetailsView の場合と同じエラーになります。
という訳で、
> (ソースコードを書かなくても、htmlソースのみで、)ListViewに配置した2つのDropDownListの連携は出来ますか?
に対する答えは、私が試した限りですが、できませんということになりました。
- 編集済み SurferOnWww 2019年12月1日 6:23 訂正
- 回答としてマーク Herokey 2019年12月2日 1:43
-
ListView を使った例をアップしておきます。CategoryName 列のドロップダウンリストから特定の Category を選ぶと、その Category に属する Products が ProductName 列のドロップダウンリストに表示されるようにしています。
基本的には以下の記事の DetailsView 例を ListView で書き直したものです。
DetailsView 中の連動 DropDownList
http://surferonwww.info/BlogEngine/post/2010/12/04/Dual-DropDownLists-in-DetailsView.aspxちなみに、環境は Windows 10 Pro 64-bit, IIS10, .NET 4.6.1, SQL Server 2008 Express, Visual Studio Community 2015 のテンプレートで作った Web サイトプロジェクトです。
.aspc.cs(コードビハインド)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; public partial class _0086CascadingDropDownListsInListView : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } // ListView.ItemEditing イベントのハンドラで編集する項目の Index は取得できるが // それを使って ItemDataBound イベントのハンドラ内で項目を特定するのが問題。 // 以下のようにするのが分かりやすくてよさそう。(全項目で探すのに抵抗があるが) // ちなみに ItemEditing イベント発生時点では FindControl で取得できないので注意。 protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e) { if (e.Item.ItemType == ListViewItemType.DataItem) { ListViewDataItem item = (ListViewDataItem)e.Item; DropDownList ddl = (DropDownList)item.FindControl("DropDownList2"); if (ddl != null) { ddl.SelectedValue = ((DataRowView)item.DataItem)["ProductID"].ToString(); } } } protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e) { Control ctrl = ((ListView)sender).Items[e.ItemIndex].FindControl("DropDownList2"); if (ctrl != null) { e.NewValues["ProductID"] = ((DropDownList)ctrl).SelectedValue; } else { e.Cancel = true; } } protected void ListView1_ItemInserting(object sender, ListViewInsertEventArgs e) { DropDownList ddlCategory = (DropDownList)e.Item.FindControl("DropDownList3"); DropDownList ddlProduct = (DropDownList)e.Item.FindControl("DropDownList4"); if (ddlCategory != null && ddlProduct != null) { e.Values["CategoryID"] = ddlCategory.SelectedValue; e.Values["ProductID"] = ddlProduct.SelectedValue; } else { e.Cancel = true; } } }
.aspx
Visual Studio のテンプレートで自動生成されるマスターページを使用(即ち、ScriptManager によるスクリプトマッピングを利用)。
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="0086CascadingDropDownListsInListView.aspx.cs" Inherits="_0086CascadingDropDownListsInListView" %> <asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" Runat="Server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server"> <%--ListView 用--%> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" DeleteCommand="DELETE FROM [Sales] WHERE ([ID] = @ID)" InsertCommand="INSERT INTO [Sales] ([CategoryID], [ProductID]) VALUES (@CategoryID, @ProductID)" SelectCommand= "SELECT s.ID, s.CategoryID, s.ProductID, c.CategoryName, p.ProductName FROM Sales AS s INNER JOIN Categories AS c ON s.CategoryID = c.CategoryID INNER JOIN Products AS p ON s.ProductID = p.ProductID" UpdateCommand="UPDATE [Sales] SET [CategoryID] = @CategoryID, [ProductID] = @ProductID WHERE ([ID] = @ID)"> <DeleteParameters> <asp:Parameter Name="ID" Type="Int32" /> </DeleteParameters> <InsertParameters> <asp:Parameter Name="CategoryID" Type="Int32" /> <asp:Parameter Name="ProductID" Type="Int32" /> </InsertParameters> <UpdateParameters> <asp:Parameter Name="CategoryID" Type="Int32" /> <asp:Parameter Name="ProductID" Type="Int32" /> <asp:Parameter Name="ID" Type="Int32" /> </UpdateParameters> </asp:SqlDataSource> <asp:ListView ID="ListView1" runat="server" DataKeyNames="ID" DataSourceID="SqlDataSource1" InsertItemPosition="LastItem" OnItemDataBound="ListView1_ItemDataBound" OnItemUpdating="ListView1_ItemUpdating" OnItemInserting="ListView1_ItemInserting"> <EditItemTemplate> <tr style=""> <td> <asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="更新" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="キャンセル" /> </td> <td> <asp:Label ID="IDLabel1" runat="server" Text='<%# Eval("ID") %>' /> </td> <td> <asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]"> </asp:SqlDataSource> <asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="SqlDataSource2" DataTextField="CategoryName" DataValueField="CategoryID" AutoPostBack="True" SelectedValue='<%# Bind("CategoryID") %>'> </asp:DropDownList> </td> <td> <asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" SelectCommand="SELECT [ProductID], [ProductName] FROM [Products] WHERE ([CategoryID] = @CategoryID)"> <SelectParameters> <asp:ControlParameter ControlID="DropDownList1" Name="CategoryID" PropertyName="SelectedValue" Type="Int32" /> </SelectParameters> </asp:SqlDataSource> <%-- SelectedValue='<%# Bind("ProductID") %>' と設定するのは NG --%> <asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="SqlDataSource3" DataTextField="ProductName" DataValueField="ProductID"> </asp:DropDownList> </td> </tr> </EditItemTemplate> <EmptyDataTemplate> <table runat="server" style=""> <tr> <td>データは返されませんでした。</td> </tr> </table> </EmptyDataTemplate> <InsertItemTemplate> <tr style=""> <td> <asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="挿入" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="クリア" /> </td> <td> </td> <td> <asp:SqlDataSource ID="SqlDataSource4" runat="server" ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]"> </asp:SqlDataSource> <asp:DropDownList ID="DropDownList3" runat="server" DataSourceID="SqlDataSource4" DataTextField="CategoryName" DataValueField="CategoryID" AutoPostBack="True"> </asp:DropDownList> </td> <td> <asp:SqlDataSource ID="SqlDataSource5" runat="server" ConnectionString="<%$ ConnectionStrings:NORTHWINDConnectionString %>" SelectCommand="SELECT [ProductID], [ProductName] FROM [Products] WHERE ([CategoryID] = @CategoryID)"> <SelectParameters> <asp:ControlParameter ControlID="DropDownList3" Name="CategoryID" PropertyName="SelectedValue" Type="Int32" /> </SelectParameters> </asp:SqlDataSource> <asp:DropDownList ID="DropDownList4" runat="server" DataSourceID="SqlDataSource5" DataTextField="ProductName" DataValueField="ProductID"> </asp:DropDownList> </td> </tr> </InsertItemTemplate> <ItemTemplate> <tr style=""> <td> <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="削除" /> <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="編集" /> </td> <td> <asp:Label ID="IDLabel" runat="server" Text='<%# Eval("ID") %>' /> </td> <td> <asp:Label ID="CategoryNameLabel" runat="server" Text='<%# Eval("CategoryName") %>' /> </td> <td> <asp:Label ID="ProductNameLabel" runat="server" Text='<%# Eval("ProductName") %>' /> </td> </tr> </ItemTemplate> <LayoutTemplate> <table runat="server"> <tr runat="server"> <td runat="server"> <table id="itemPlaceholderContainer" runat="server" border="0" style=""> <tr runat="server" style=""> <th runat="server"></th> <th runat="server">ID</th> <th runat="server">CategoryName</th> <th runat="server">ProductName</th> </tr> <tr id="itemPlaceholder" runat="server"> </tr> </table> </td> </tr> <tr runat="server"> <td runat="server" style=""></td> </tr> </table> </LayoutTemplate> </asp:ListView> </asp:Content>
- 回答としてマーク Herokey 2019年12月3日 7:52
-
SurferOnWwwさん
マスターページ付きで開始したのですが、難しそうだったので、先ずは、マスターページなしで、その他はSurferOnWwwさんのやり方を参考にやった所、挿入、更新、削除が出来ました。ただし、部店と扱者はコード表示です。
.aspxにおいて、DropDownListで使用するSqlDataSourceの定義を同一tdタグ内に配置せず、一番下に置いたまま使っていたのも上手くいかなかった原因の1つだったと考えます。以前、配置するように言われたにもかかわらず。。。
また、ListViewの「オプティミスティック同時実行制御」を有効にした所、削除が上手くいかなかったので、無効にして作り直しました。
.aspx.csはこれから理解します。
迅速な回答をありがとうございます。
なお、前回は別のソリューションの.aspxを貼り付けてしまったようで、失礼しました。
.aspx.cs(コードビハインド)
using System; using System.Data; using System.Web.UI; using System.Web.UI.WebControls; namespace GaisaiNewAcctMaintenanceTest2019120301 { public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e) { if (e.Item.ItemType == ListViewItemType.DataItem) { ListViewDataItem item = (ListViewDataItem)e.Item; DropDownList ddl = (DropDownList)item.FindControl("AtkaiCDDropDownListE"); if (ddl != null) { ddl.SelectedValue = ((DataRowView)item.DataItem)["AtkaiCD"].ToString(); } } } protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e) { Control ctrl = ((ListView)sender).Items[e.ItemIndex].FindControl("AtkaiCDDropDownListE"); if (ctrl != null) { e.NewValues["AtkaiCD"] = ((DropDownList)ctrl).SelectedValue; } else { e.Cancel = true; } } protected void ListView1_ItemInserting(object sender, ListViewInsertEventArgs e) { DropDownList ddl_BtnCD = (DropDownList)e.Item.FindControl("BtnCDDropDownListI"); DropDownList ddl_AtkaiCD = (DropDownList)e.Item.FindControl("AtkaiCDDropDownListI"); if (ddl_BtnCD != null && ddl_AtkaiCD != null) { e.Values["BtnCD"] = ddl_BtnCD.SelectedValue; e.Values["AtkaiCD"] = ddl_AtkaiCD.SelectedValue; } else { e.Cancel = true; } } } }
.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="GaisaiNewAcctMaintenanceTest2019120301.WebForm1" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:ListView ID="ListView1" runat="server" DataKeyNames="ActNo" DataSourceID="SqlDataSource1" InsertItemPosition="LastItem" OnItemDataBound="ListView1_ItemDataBound" OnItemInserting="ListView1_ItemInserting" OnItemUpdating="ListView1_ItemUpdating"> <AlternatingItemTemplate> <tr style=""> <td> <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="削除" /> <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="編集" /> </td> <td> <asp:Label ID="BtnCDLabel" runat="server" Text='<%# Eval("BtnCD") %>' /> </td> <td> <asp:Label ID="AtkaiCDLabel" runat="server" Text='<%# Eval("AtkaiCD") %>' /> </td> <td> <asp:Label ID="ActNoLabel" runat="server" Text='<%# Eval("ActNo") %>' /> </td> </tr> </AlternatingItemTemplate> <EditItemTemplate> <tr style=""> <td> <asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="更新" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="キャンセル" /> </td> <td> <asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:complianceConnectionString6 %>" SelectCommand="SELECT [BtnCD] FROM [butn]"></asp:SqlDataSource> <asp:DropDownList ID="BtnCDDropDownListE" runat="server" DataSourceID="SqlDataSource2" DataTextField="BtnCD" DataValueField="BtnCD" AutoPostBack="True" SelectedValue='<%# Bind("BtnCD") %>'> </asp:DropDownList> </td> <td> <asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:complianceConnectionString7 %>" SelectCommand="SELECT [AtkaiCD] FROM [atsu] WHERE ([BtnCD] = @BtnCD)"> <SelectParameters> <asp:ControlParameter ControlID="BtnCDDropDownListE" Name="BtnCD" PropertyName="SelectedValue" Type="String" /> </SelectParameters> </asp:SqlDataSource> <asp:DropDownList ID="AtkaiCDDropDownListE" runat="server" DataSourceID="SqlDataSource3" DataTextField="AtkaiCD" DataValueField="AtkaiCD"> </asp:DropDownList> </td> <td> <asp:Label ID="ActNoLabel1" runat="server" Text='<%# Eval("ActNo") %>' /> </td> </tr> </EditItemTemplate> <EmptyDataTemplate> <table runat="server" style=""> <tr> <td>データは返されませんでした。</td> </tr> </table> </EmptyDataTemplate> <InsertItemTemplate> <tr style=""> <td> <asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="挿入" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="クリア" /> </td> <td> <asp:SqlDataSource ID="SqlDataSource4" runat="server" ConnectionString="<%$ ConnectionStrings:complianceConnectionString8 %>" SelectCommand="SELECT [BtnCD] FROM [butn]"></asp:SqlDataSource> <asp:DropDownList ID="BtnCDDropDownListI" runat="server" DataSourceID="SqlDataSource4" DataTextField="BtnCD" DataValueField="BtnCD" AutoPostBack="True"> </asp:DropDownList> </td> <td> <asp:SqlDataSource ID="SqlDataSource5" runat="server" ConnectionString="<%$ ConnectionStrings:complianceConnectionString9 %>" SelectCommand="SELECT [AtkaiCD] FROM [atsu] WHERE ([BtnCD] = @BtnCD)"> <SelectParameters> <asp:ControlParameter ControlID="BtnCDDropDownListI" Name="BtnCD" PropertyName="SelectedValue" Type="String" /> </SelectParameters> </asp:SqlDataSource> <asp:DropDownList ID="AtkaiCDDropDownListI" runat="server" DataSourceID="SqlDataSource5" DataTextField="AtkaiCD" DataValueField="AtkaiCD"> </asp:DropDownList> </td> <td> <asp:TextBox ID="ActNoTextBox" runat="server" Text='<%# Bind("ActNo") %>' /> </td> </tr> </InsertItemTemplate> <ItemTemplate> <tr style=""> <td> <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="削除" /> <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="編集" /> </td> <td> <asp:Label ID="BtnCDLabel" runat="server" Text='<%# Eval("BtnCD") %>' /> </td> <td> <asp:Label ID="AtkaiCDLabel" runat="server" Text='<%# Eval("AtkaiCD") %>' /> </td> <td> <asp:Label ID="ActNoLabel" runat="server" Text='<%# Eval("ActNo") %>' /> </td> </tr> </ItemTemplate> <LayoutTemplate> <table runat="server"> <tr runat="server"> <td runat="server"> <table id="itemPlaceholderContainer" runat="server" border="0" style=""> <tr runat="server" style=""> <th runat="server"></th> <th runat="server">BtnCD</th> <th runat="server">AtkaiCD</th> <th runat="server">ActNo</th> </tr> <tr id="itemPlaceholder" runat="server"> </tr> </table> </td> </tr> <tr runat="server"> <td runat="server" style=""> <asp:DataPager ID="DataPager1" runat="server"> <Fields> <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" ShowLastPageButton="True" /> </Fields> </asp:DataPager> </td> </tr> </table> </LayoutTemplate> <SelectedItemTemplate> <tr style=""> <td> <asp:Button ID="DeleteButton" runat="server" CommandName="Delete" Text="削除" /> <asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="編集" /> </td> <td> <asp:Label ID="BtnCDLabel" runat="server" Text='<%# Eval("BtnCD") %>' /> </td> <td> <asp:Label ID="AtkaiCDLabel" runat="server" Text='<%# Eval("AtkaiCD") %>' /> </td> <td> <asp:Label ID="ActNoLabel" runat="server" Text='<%# Eval("ActNo") %>' /> </td> </tr> </SelectedItemTemplate> </asp:ListView> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:complianceConnectionString %>" DeleteCommand="DELETE FROM [acct_new] WHERE [ActNo] = @ActNo" InsertCommand="INSERT INTO [acct_new] ([BtnCD], [AtkaiCD], [ActNo]) VALUES (@BtnCD, @AtkaiCD, @ActNo)" SelectCommand="SELECT [BtnCD], [AtkaiCD], [ActNo] FROM [acct_new]" UpdateCommand="UPDATE [acct_new] SET [BtnCD] = @BtnCD, [AtkaiCD] = @AtkaiCD WHERE [ActNo] = @ActNo"> <DeleteParameters> <asp:Parameter Name="ActNo" Type="String" /> </DeleteParameters> <InsertParameters> <asp:Parameter Name="BtnCD" Type="String" /> <asp:Parameter Name="AtkaiCD" Type="String" /> <asp:Parameter Name="ActNo" Type="String" /> </InsertParameters> <UpdateParameters> <asp:Parameter Name="BtnCD" Type="String" /> <asp:Parameter Name="AtkaiCD" Type="String" /> <asp:Parameter Name="ActNo" Type="String" /> </UpdateParameters> </asp:SqlDataSource> <br /> </div> </form> </body> </html>