次のように、リストボックスとユーザーコントロールが更新パネル内に配置されたページがあります。
<%@ Register TagPrefix="uc1" TagName="CMessage" Src="~/Controls/CMessage.ascx" %>
<ajaxToolkit:ToolkitScriptManager runat="server" ID="ToolkitScriptManager1" EnableScriptGlobalization="true" EnableScriptLocalization="true" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:ListBox ID="lbox" runat="server"></asp:ListBox>
<asp:Button ID="btnDelete" OnClick="btnDelete_Click" runat="server" Text="Delete selected item" Enabled="True"></asp:Button>
<uc1:CMessage ID="CMessage1" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
ページの分離コードは次のようになります。
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
lbox.Items.Add("test1");
lbox.Items.Add("test2");
}
}
protected void btnDelete_Click(object sender, EventArgs e)
{
CMessage.MessageConfirm("Delete item?", "Yes", "No", DeleteItem);
}
protected void DeleteItem()
{
lbox.Items.Remove(lbox.SelectedItem);
CMessage.Message("Item deleted succesfully!");
}
ユーザーコントロールは次のようになります。
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CMessage.ascx.cs" Inherits="Controles.CMessage" %>
<table id="tableMessage" runat="server" style="display: none" class="modalPopup">
<tr>
<td>
<asp:Label ID="lb5" runat="server" Text="Message"></asp:Label>
</td>
</tr>
<tr>
<td>
<asp:Label ID="lbMessage" runat="server"></asp:Label>
</td>
</tr>
<tr>
<td>
<asp:Button ID="btnOk" runat="server" Text="Ok" OnClick="btnOk_Click" />
<asp:Button ID="btnCancel" runat="server" Text="Cancel" OnClick="btnCancel_Click" />
</td>
</tr>
</table>
<asp:Button ID="btnOKError" runat="server" Text="OK" style="display: none" />
<ajaxToolkit:ModalPopupExtender ID="ModalPopupMessage" runat="server" TargetControlID="btnOKError" PopupControlID="tableMessage" OkControlID="btnOKError" CancelControlID="btnOKError"></ajaxToolkit:ModalPopupExtender>
ユーザーコントロールの分離コードは次のようになります。
public partial class CMensaje : UserControl
{
public delegate void FunctionButtonPressed();
private FunctionButtonPressed FunctionButtonPressedOk
{
get { return (FunctionButtonPressed)Session["FunctionButtonPressedOk"]; }
set { Session["FunctionButtonPressedOk"]= value; }
}
protected void btnOk_Click(object sender, EventArgs e)
{
ModalPopupMenssage.Hide();
if (FunctionButtonPressedOk!= null)
{
FunctionButtonPressedOk();
}
}
protected void btnCancel_Click(object sender, EventArgs e)
{
ModalPopupMessage.Hide();
}
public void Mensaje(string message)
{
lbMessage.Text = message;
FunctionButtonPressedOk= null;
btnCancel.Visible = false;
ModalPopupMessage.Show();
}
public void MessageConfirm(string message, FunctionButtonPressed FunButtonOkx)
{
lbMessage.Text = message;
FunctionButtonPressedOk= FunBotonAceptarx;
btnCancel.Visible = true;
ModalPopupMensaje.Show();
}
}
すべてが機能し、ポップアップが表示され、ページから呼び出す関数がユーザーコントロールに渡され、ユーザーが [ok] を押して正しくトリガーした場合などにトリガーされます。しかし、最後の関数 DeleteItem() では、ページに加えられた変更 (このたとえば、リストボックスから削除されたアイテムと通知メッセージが起動された場合) は機能しません。
更新パネルが更新されないようです。いつものように更新モードがあるため、手動で UpdatePanel1.Update() を呼び出すことはできません。理論的には、ページサイクルのこの部分では、変更でページを更新する必要があります...
ユーザー コントロールのページロードに、UpdatePanel の PostBackTrigger として [OK] ボタンを追加しようとしましたが、役に立ちませんでした。
これはページとユーザー コントロールのスリム化されたバージョンであることを覚えておいてください。これにより、人々は目前の問題に集中できるようになります。詳細が必要な場合は、私に尋ねてください...
コード フローは次のようになります。
ユーザーがアイテムの削除ボタンをクリックし、ページで btnDelete_Click() をトリガーします (最初のポストバック)
btnDelete_Click() は、ユーザー コントロール CMessage.MessageConfirm を呼び出し、DeleteItem を引数として渡します。
ユーザーコントロールで MessageConfirm() は modalpopup を表示し、後で呼び出すために引数関数 DeleteItem() を保存します (最初のポストバックの終わり)
modalpopup を表示した後、ユーザーは [OK] ボタンをクリックし、ユーザー コントロールで btnOk_Click() をトリガーします (2 番目のポストバック)。
ユーザーコントロールで btnOk_Click() は、以前に保存された DeleteItem() 関数を呼び出します
ページで DeleteItem() が ListBox から項目を削除します (簡略化するために 2 番目のメッセージを呼び出さないとします。これは 2 番目のポストバックの終わりであり、更新パネルは更新されていません:S)
問題を切り分け、すべてのコントロールと関数をユーザーコントロールからページに移動したと思いますが、問題は解決しませんでしたが、デリゲートの代わりに DeleteItem() 関数を直接呼び出すと、機能しました (両方のケースでDeleteItem() でブレークポイントがトリガーされたため、関数コードは正しく実行されていました):
protected void btnOk_Click(object sender, EventArgs e)
{
ModalPopupMenssage.Hide();
/*if (FunctionButtonPressedOk!= null)
{
FunctionButtonPressedOk();
}*/
DeleteItem(); //page updates correctly! why?
}
デリゲートとの非互換性はありますか?