0

次のように、リストボックスとユーザーコントロールが更新パネル内に配置されたページがあります。

<%@ 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] ボタンを追加しようとしましたが、役に立ちませんでした。

これはページとユーザー コントロールのスリム化されたバージョンであることを覚えておいてください。これにより、人々は目前の問題に集中できるようになります。詳細が必要な場合は、私に尋ねてください...

コード フローは次のようになります。

  1. ユーザーがアイテムの削除ボタンをクリックし、ページで btnDelete_Click() をトリガーします (最初のポストバック)

  2. btnDelete_Click() は、ユーザー コントロール CMessage.MessageConfirm を呼び出し、DeleteItem を引数として渡します。

  3. ユーザーコントロールで MessageConfirm() は modalpopup を表示し、後で呼び出すために引数関数 DeleteItem() を保存します (最初のポストバックの終わり)

  4. modalpopup を表示した後、ユーザーは [OK] ボタンをクリックし、ユーザー コントロールで btnOk_Click() をトリガーします (2 番目のポストバック)。

  5. ユーザーコントロールで btnOk_Click() は、以前に保存された DeleteItem() 関数を呼び出します

  6. ページで 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?
    }

デリゲートとの非互換性はありますか?

4

1 に答える 1

0

最後に、次の行を変更して解決しました:

if (FunctionButtonPressedOk!= null)
        {
            //FunctionButtonPressedOk();
            Page.GetType().InvokeMember(FunctionButtonPressedOk.Method.Name, BindingFlags.InvokeMethod, null, Page, new []{sender, e});
        }

なぜこのように動作するのですか?内部の違いは何ですか?

于 2012-05-16T08:35:58.117 に答える