トップ回答者
ユーザコントロールの ModalPopupExtender ボタン押下で 親画面ラベルのTextを変更させたい

質問
-
お世話になっております。
ASP.NET Webフォームで AJAX Control Toolkit を使用して開発中なのですが、
ユーザコントロールを用いた場合の制御が上手くいきません。
(ユーザコントロール部分をページ直書きだとうまくいきます)
どなたかご助言いただけないでしょうか。
OS: Windows 7 Pro
ASP.NET Framework 4.7 (Webフォーム)
言語: C#
開発環境: Visual Studio 2017
ブラウザ: IE11
実装目標
(1) ユーザコントロールに、モーダルダイアログを実装。
(2) 親画面のボタン押下で、(1)のユーザダイアログを表示。
(3)「実行しますか?」のダイアログの OKボタンのイベントで、
親画面のラベルに「実行しました」等のメッセージを表示。
親画面で、「OK」または、「キャンセル」の押下を引数で条件分岐させる
ことはできているのですが、ラベルの表示変更をさせることができません。
ラベルのTextプロパティに正しく値は渡されています。
[ユーザコントロール.ascx]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
<%@ Control Language="C#" AutoEventWireup="false" CodeBehind="DialogMessage.ascx.cs" Inherits="UserControl.DialogMessage" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<!-- ダミーボタン(非表示) -->
<asp:Button ID="btnDummy" runat="server" Text="Button" Style="display: none" />
<!-- ポップアップ部分 -->
<asp:Panel ID="pnlDialog" runat="server">
<div class="dialog">
<div class="content">
<div class="message">
<asp:Label ID="lblMsg" runat="server"></asp:Label>
</div>
</div>
<br class="clearfloat" />
<div class="button">
<asp:Button ID="btnOk" Text="OK" OnClick="btnOk_Click" runat="server" />
<asp:Button ID="btnCancel" Text="Cancel" OnClick="btnCancel_Click" runat="server" />
</div>
</div>
</asp:Panel>
<!-- ModalPopupExtender -->
<asp:ModalPopupExtender ID="mpeCommon" TargetControlID="btnDummy" PopupControlID="pnlDialog"
DropShadow="true" Drag="false"
PopupDragHandleControlID="pnlDialog"
CancelControlID="btnCancel"
BackgroundCssClass="modalBackground"
runat="server"/>
[ユーザコントロール.ascx.cs]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// <summary>
/// ボタン押下時の引数
/// </summary>
public class OnButtonEventArgs : EventArgs
{
#region プロパティ
/// <summary>
/// 押下ボタンのタイプ
/// </summary>
public Const.DialogResultType ResultType { get; set; }
#endregion プロパティ
#region コンストラクタ
public OnButtonEventArgs()
{
}
#endregion コンストラクタ
}
/// <summary>
/// ポップアップ表示クラス
/// </summary>
public partial class DialogMessage : System.Web.UI.UserControl
{
#region public変数(イベント)
public delegate void DialogClosedHandler(object sender, OnButtonEventArgs e);
public event DialogClosedHandler DialogClosed;
#endregion public変数(イベント)
#region プロパティ
/// <summary>
/// メッセージ プロパティ
/// </summary>
public string Message
{
get
{
return this.Message;
}
set
{
this.lblMsg.Text = value;
}
}
#endregion プロパティ
#region イベント
protected void Page_Load(object sender, EventArgs e)
{
}
#endregion イベント
#region publicメソッド
/// <summary>
/// ダイアログ表示
/// </summary>
public void Show()
{
try
{
// ModalPopupExtender 表示
this.mpeCommon.Show();
OnButtonEventArgs e = new OnButtonEventArgs();
// 初期値設定
e.ResultType = Const.DialogResultType.None;
this.DialogClosed(this, e);
Session[Const.SessionItem.DialogClosed] = this.DialogClosed;
}
catch (Exception ex)
{
string error = ex.ToString();
}
}
#endregion publicメソッド
#region コンストラクタ
/// <summary>
/// コンストラクタ
/// </summary>
public DialogMessage()
{
}
#endregion コンストラクタ
/// <summary>
/// OKボタン押下時
/// </summary>
protected void btnOk_Click(object sender, EventArgs e)
{
OnButtonEventArgs eventArgs = new OnButtonEventArgs();
eventArgs.ResultType = Const.DialogResultType.OK;
this.DialogClosed = (DialogClosedHandler)Session[Const.SessionItem.DialogClosed];
DialogClosed(this, eventArgs);
}
}
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[親画面.aspx]
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="DialogTest.WebForm1" %>
<%@ Register Src="~/UserControl/DialogMessage.ascx" TagPrefix="uc1" TagName="DialogMessage" %>
<!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>
<link href="~/Content/DialogMessage.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ToolkitScriptManager1" runat="server" />
<uc1:DialogMessage runat="server" id="DialogMessage" />
<div>
<asp:Button ID="btnMessage" Text="ポップアップ" OnClick="btnMessage_Click" runat="server" />
</div>
<div>
<asp:Label ID="lblTest" Text="テストラベル" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[親画面.aspx.cs]
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(Page.IsPostBack == false)
{
this.lblTest.Text = "Load時設定";
this.lblTest.BackColor = Color.Aqua;
}
}
protected void btnMessage_Click(object sender, EventArgs e)
{
this.DialogMessage.Message = "メッセージ";
this.DialogMessage.DialogClosed += new DialogMessage.DialogClosedHandler(DialogMessage_DialogClosed);
this.DialogMessage.Show();
}
/// <summary>
/// ダイアログ押下時の処理
/// </summary>
private void DialogMessage_DialogClosed(object sender, OnButtonEventArgs e)
{
Const.DialogResultType btnType = e.ResultType;
// OKなら処理続行
if (btnType == Const.DialogResultType.OK)
{
this.lblTest.Text = "OK を選択";
this.lblTest.BackColor = Color.GreenYellow;
}
// Cancelなら処理中断
else if(btnType == Const.DialogResultType.Cancel)
{
this.lblTest.Text = "Cancel を選択";
this.lblTest.BackColor = Color.IndianRed;
}
}
}
回答
-
> 改めてソースを見直し、削れるだけ削りました。
> また、定数クラスを参照している箇所を文字列に変更しました。質問者さんがアップされたコードは定義不明な Const.SessionItem.DialogClosed とかがあったり、OnClick="btnCancel_Click" に設定した btnCancel_Click ハンドラがないなど、そのままでは動かないのですが・・・とりあえず動くように直して実行してみました。
結果、質問者さんが最初の質問に書いた、
> 親画面で、「OK」または、「キャンセル」の押下を引数で条件分岐させる
> ことはできているのですが、ラベルの表示変更をさせることができません。は再現できました。
> ラベルのTextプロパティに正しく値は渡されています。
そこが不可解なのですが、イベントを Session に保持してポストバック前後で使い回すという ASP.NET としては想定外(?)のことを行っているので、想定外のミステリアスな結果になっているような気がします。
想定外というのは結果からそういう気がするだけで確証はありませんが、イベントを Session に保持してポストバック前後で使い回すということを止めれば、少なくとも「ラベルの表示変更をさせることができません」という問題は回避できました。(ラベルには "OK を選択" が表示されました)
具体的にどのようにしたかと言うと:
[ユーザコントロール.ascx.cs] の Show メソッドで以下をコメントアウト
Session[Const.SessionItem.DialogClosed] = this.DialogClosed;
[ユーザコントロール.ascx.cs] の btnOk_Click メソッドで以下をコメントアウト
this.DialogClosed = (DialogClosedHandler)Session[Const.SessionItem.DialogClosed];
[親画面.aspx.cs] で btnMessage_Click メソッドの以下のコードを Page_Load に移動
this.DialogMessage.DialogClosed
+= new DialogMessage.DialogClosedHandler(DialogMessage_DialogClosed);お試しください。少なくとも「ラベルの表示変更をさせることができません」という問題は回避できると思います。
#何でイベントハンドラを使ってそのような複雑なことをしているのか分かりません。もっと簡単かつスマートは方法がありそうな気がしますが・・・
- 回答としてマーク 栗下 望Microsoft employee, Moderator 2018年1月5日 2:44
-
> イベントハンドラを使わず、どのような実装をなさるかアイデアをいただけないでしょうか。
イベントハンドラは使うのですが、2 段階にするというような複雑なことはしなくても済みそうだということです。
質問者さんのやりたいこと全てを把握しているわけではないのでハズレかもしれませんが、単にユーザーコントロールに配置した Button の Click イベントに任意のハンドラをアタッチしたいということでよければ、.aspx ページで FindControl を使ってユーザーコントロールの Button を探してハンドラをアタッチできます。
スマートかどうかは主観もあるのでともかくとして、コードはかなり簡単になると思います。そういうだけでは分かり難いと思いますのでサンプルをアップしておきます。
0004-ModalPopup.ascx.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebFormsApp { public partial class _0004_ModalPopup : System.Web.UI.UserControl { public string Message { set { this.lblMsg.Text = value; } } public void Show() { this.mpeCommon.Show(); } } }
0004-ModalPopup.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="0004-ModalPopup.ascx.cs" Inherits="WebFormsApp._0004_ModalPopup" %> <asp:Button ID="btnDummy" runat="server" Text="Button" Style="display: none" /> <asp:Panel ID="pnlDialog" runat="server"> <div> <asp:Label ID="lblMsg" runat="server"></asp:Label> </div> <br /> <div> <asp:Button ID="btnOk" Text="OK" runat="server" /> <asp:Button ID="btnCancel" Text="Cancel" runat="server" /> </div> </asp:Panel> <%--CancelControlID="btnCancel" を設定するとクリックしてもポストバックしない。 結果、イベントハンドラに制御が飛ばないので注意。--%> <ajaxToolkit:ModalPopupExtender ID="mpeCommon" TargetControlID="btnDummy" PopupControlID="pnlDialog" runat="server"> </ajaxToolkit:ModalPopupExtender>
0004-UserControlTest.aspx.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebFormsApp { public partial class _0004_UserControlTest : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Button ok = (Button)this.ModalPopupUserControl1.FindControl("btnOk"); ok.Click += Ok_Click; // CancelControlID = "btnCancel" を設定すると btnCancel をクリックしても // ポストバックしない(クライアント側で ModalPopup を非表示にするのみ)。 // 結果、Page_Load は実行されず、イベントハンドラも実行されないので注意。 Button cancel = (Button)this.ModalPopupUserControl1.FindControl("btnCancel"); cancel.Click += Cancel_Click; } private void Ok_Click(object sender, EventArgs e) { this.lblTest.Text = "OK を選択"; } private void Cancel_Click(object sender, EventArgs e) { this.lblTest.Text = "Cancel を選択"; } protected void btnMessage_Click(object sender, EventArgs e) { this.ModalPopupUserControl1.Message = "メッセージ"; this.ModalPopupUserControl1.Show(); } } }
0004-UserControlTest.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="0004-UserControlTest.aspx.cs" Inherits="WebFormsApp._0004_UserControlTest" %> <%@ Register Src="~/0004-ModalPopup.ascx" TagPrefix="uc1" TagName="ModalPopupUserControl" %> <!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"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <uc1:ModalPopupUserControl runat="server" id="ModalPopupUserControl1" /> <asp:Button ID="btnMessage" Text="ポップアップ" OnClick="btnMessage_Click" runat="server" /> <br /> <asp:Label ID="lblTest" runat="server"></asp:Label> </form> </body> </html>
- 回答としてマーク 栗下 望Microsoft employee, Moderator 2018年1月5日 2:44
すべての返信
-
大晦日にお付き合い頂き、コメントありがとうございます。
また、長々とソースを貼り付けてしまい申し訳ありません。
改めてソースを見直し、削れるだけ削りました。
また、定数クラスを参照している箇所を文字列に変更しました。
ModalPopupExtenderは、イベント絡んでいるため、削って問題再現をすることが
できませんでした。下記、ソースでご教授いただけますでしょうか。
[ユーザコントロール.ascx]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
<asp:Button ID="btnDummy" runat="server" Text="Button" Style="display: none" />
<asp:Panel ID="pnlDialog" runat="server">
<div class="dialog">
<div class="content">
<div class="message">
<asp:Label ID="lblMsg" runat="server"></asp:Label>
</div>
</div>
<br class="clearfloat" />
<div class="button">
<asp:Button ID="btnOk" Text="OK" OnClick="btnOk_Click" runat="server" />
<asp:Button ID="btnCancel" Text="Cancel" OnClick="btnCancel_Click" runat="server" />
</div>
</div>
</asp:Panel>
<asp:ModalPopupExtender ID="mpeCommon" TargetControlID="btnDummy" PopupControlID="pnlDialog"
DropShadow="true" Drag="false"
PopupDragHandleControlID="pnlDialog"
CancelControlID="btnCancel"
BackgroundCssClass="modalBackground"
runat="server"/>
[ユーザコントロール.ascx.cs]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public class OnButtonEventArgs : EventArgs
{
public string ResultType { get; set; }
}
public partial class DialogMessage : System.Web.UI.UserControl
{
public delegate void DialogClosedHandler(object sender, OnButtonEventArgs e);
public event DialogClosedHandler DialogClosed;
public string Message
{
set
{
this.lblMsg.Text = value;
}
}
public void Show()
{
try
{
this.mpeCommon.Show();
OnButtonEventArgs e = new OnButtonEventArgs();
e.ResultType = "None";
this.DialogClosed(this, e);
Session[Const.SessionItem.DialogClosed] = this.DialogClosed;
}
}
protected void btnOk_Click(object sender, EventArgs e)
{
OnButtonEventArgs eventArgs = new OnButtonEventArgs();
eventArgs.ResultType = "OK";
this.DialogClosed = (DialogClosedHandler)Session[Const.SessionItem.DialogClosed];
DialogClosed(this, eventArgs);
}
}
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[親画面.aspx]
<form id="form1" runat="server">
<asp:ScriptManager ID="ToolkitScriptManager1" runat="server" />
<uc1:DialogMessage runat="server" id="DialogMessage" />
<div>
<asp:Button ID="btnMessage" Text="ポップアップ" OnClick="btnMessage_Click" runat="server" />
</div>
<div>
<asp:Label ID="lblTest" runat="server"></asp:Label>
</div>
</form>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[親画面.aspx.cs]
protected void btnMessage_Click(object sender, EventArgs e)
{
this.DialogMessage.Message = "メッセージ";
this.DialogMessage.DialogClosed
+= new DialogMessage.DialogClosedHandler(DialogMessage_DialogClosed);
this.DialogMessage.Show();
}
private void DialogMessage_DialogClosed(object sender, OnButtonEventArgs e)
{
string btnType = e.ResultType;
if (btnType == "OK")
{
this.lblTest.Text = "OK を選択";
}
} -
> 改めてソースを見直し、削れるだけ削りました。
> また、定数クラスを参照している箇所を文字列に変更しました。質問者さんがアップされたコードは定義不明な Const.SessionItem.DialogClosed とかがあったり、OnClick="btnCancel_Click" に設定した btnCancel_Click ハンドラがないなど、そのままでは動かないのですが・・・とりあえず動くように直して実行してみました。
結果、質問者さんが最初の質問に書いた、
> 親画面で、「OK」または、「キャンセル」の押下を引数で条件分岐させる
> ことはできているのですが、ラベルの表示変更をさせることができません。は再現できました。
> ラベルのTextプロパティに正しく値は渡されています。
そこが不可解なのですが、イベントを Session に保持してポストバック前後で使い回すという ASP.NET としては想定外(?)のことを行っているので、想定外のミステリアスな結果になっているような気がします。
想定外というのは結果からそういう気がするだけで確証はありませんが、イベントを Session に保持してポストバック前後で使い回すということを止めれば、少なくとも「ラベルの表示変更をさせることができません」という問題は回避できました。(ラベルには "OK を選択" が表示されました)
具体的にどのようにしたかと言うと:
[ユーザコントロール.ascx.cs] の Show メソッドで以下をコメントアウト
Session[Const.SessionItem.DialogClosed] = this.DialogClosed;
[ユーザコントロール.ascx.cs] の btnOk_Click メソッドで以下をコメントアウト
this.DialogClosed = (DialogClosedHandler)Session[Const.SessionItem.DialogClosed];
[親画面.aspx.cs] で btnMessage_Click メソッドの以下のコードを Page_Load に移動
this.DialogMessage.DialogClosed
+= new DialogMessage.DialogClosedHandler(DialogMessage_DialogClosed);お試しください。少なくとも「ラベルの表示変更をさせることができません」という問題は回避できると思います。
#何でイベントハンドラを使ってそのような複雑なことをしているのか分かりません。もっと簡単かつスマートは方法がありそうな気がしますが・・・
- 回答としてマーク 栗下 望Microsoft employee, Moderator 2018年1月5日 2:44
-
年明け早々、ご教授頂き誠にありがとうございました。
SurferOnWww様の通りの修正で、無事意図した実装になりました。
初回では、ご指摘の通り、定義元のない定義込みのソースを掲載してしまい
重ね重ね申し訳ありませんでした。
>> ラベルのTextプロパティに正しく値は渡されています。
>そこが不可解なのですが、イベントを Session に保持してポストバック前後で使い回すという
>ASP.NET としては想定外(?)のことを行っているので、想定外のミステリアスな結果になっているような気がします。
ASP.NET 初めての実装なのですが、全くの常識外のことをやっていたのですね。
短納期で、基礎を理解せず進めたためでお恥ずかしいです。
> #何でイベントハンドラを使ってそのような複雑なことをしているのか分かりません。
> もっと簡単かつスマートは方法がありそうな気がしますが・・・
元々、VB.NET で掲載されたソースがイベントハンドラを使用していました。
それをC# に移植したものでした。
探した中では、下記2項目とも満たすサンプルは他に見つけられませんでした。
・モーダルを表示
・押下ボタンの種類を親画面に渡して、条件分岐
「もっと簡単かつスマートな方法」、是非、そのような実装をしたいところです。
大変図々しいお願いなのですが、
SurferOnWww様でしたら、イベントハンドラを使わず、どのような実装を
なさるかアイデアをいただけないでしょうか。
大まかな流れなどで構いません。
後は、悪戦苦闘してでも、挑戦してみたいと思います。 -
> イベントハンドラを使わず、どのような実装をなさるかアイデアをいただけないでしょうか。
イベントハンドラは使うのですが、2 段階にするというような複雑なことはしなくても済みそうだということです。
質問者さんのやりたいこと全てを把握しているわけではないのでハズレかもしれませんが、単にユーザーコントロールに配置した Button の Click イベントに任意のハンドラをアタッチしたいということでよければ、.aspx ページで FindControl を使ってユーザーコントロールの Button を探してハンドラをアタッチできます。
スマートかどうかは主観もあるのでともかくとして、コードはかなり簡単になると思います。そういうだけでは分かり難いと思いますのでサンプルをアップしておきます。
0004-ModalPopup.ascx.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebFormsApp { public partial class _0004_ModalPopup : System.Web.UI.UserControl { public string Message { set { this.lblMsg.Text = value; } } public void Show() { this.mpeCommon.Show(); } } }
0004-ModalPopup.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="0004-ModalPopup.ascx.cs" Inherits="WebFormsApp._0004_ModalPopup" %> <asp:Button ID="btnDummy" runat="server" Text="Button" Style="display: none" /> <asp:Panel ID="pnlDialog" runat="server"> <div> <asp:Label ID="lblMsg" runat="server"></asp:Label> </div> <br /> <div> <asp:Button ID="btnOk" Text="OK" runat="server" /> <asp:Button ID="btnCancel" Text="Cancel" runat="server" /> </div> </asp:Panel> <%--CancelControlID="btnCancel" を設定するとクリックしてもポストバックしない。 結果、イベントハンドラに制御が飛ばないので注意。--%> <ajaxToolkit:ModalPopupExtender ID="mpeCommon" TargetControlID="btnDummy" PopupControlID="pnlDialog" runat="server"> </ajaxToolkit:ModalPopupExtender>
0004-UserControlTest.aspx.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebFormsApp { public partial class _0004_UserControlTest : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Button ok = (Button)this.ModalPopupUserControl1.FindControl("btnOk"); ok.Click += Ok_Click; // CancelControlID = "btnCancel" を設定すると btnCancel をクリックしても // ポストバックしない(クライアント側で ModalPopup を非表示にするのみ)。 // 結果、Page_Load は実行されず、イベントハンドラも実行されないので注意。 Button cancel = (Button)this.ModalPopupUserControl1.FindControl("btnCancel"); cancel.Click += Cancel_Click; } private void Ok_Click(object sender, EventArgs e) { this.lblTest.Text = "OK を選択"; } private void Cancel_Click(object sender, EventArgs e) { this.lblTest.Text = "Cancel を選択"; } protected void btnMessage_Click(object sender, EventArgs e) { this.ModalPopupUserControl1.Message = "メッセージ"; this.ModalPopupUserControl1.Show(); } } }
0004-UserControlTest.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="0004-UserControlTest.aspx.cs" Inherits="WebFormsApp._0004_UserControlTest" %> <%@ Register Src="~/0004-ModalPopup.ascx" TagPrefix="uc1" TagName="ModalPopupUserControl" %> <!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"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <uc1:ModalPopupUserControl runat="server" id="ModalPopupUserControl1" /> <asp:Button ID="btnMessage" Text="ポップアップ" OnClick="btnMessage_Click" runat="server" /> <br /> <asp:Label ID="lblTest" runat="server"></asp:Label> </form> </body> </html>
- 回答としてマーク 栗下 望Microsoft employee, Moderator 2018年1月5日 2:44
-
SurferOnWww様
サンプルまでご提示下さって、本当にありがとうございます!!
なんとお礼申し上げたらよいか分かりません。
早速、実装、動作させてみました。
ご提示してくださったソースは、ずっとすっきりして分かりやすいと感じました。
ユーザコントロールから FindControlメソッドを使うということは全く思いつきませんでした。
また、CancelControlID="btnCancel" についての丁寧なコメントありがとうございました。
早速この新しいユーザコントロールを組み込んで使っていきます。
年末年始の恐らく休暇中でしたところを、お時間とお手間頂き誠にありがとうございました。