1

我在同一服务器端调用中隐藏一个 ModalPopupExtender 并显示另一个时遇到问题。

我的应用程序需要用户输入某些验证条件。这些条件按顺序进行评估,当某些条件为真时,需要用户通过 ModalPopupExtender 窗口进行验证(单击是或否)。如果用户单击是,评估应该继续,如果另一个条件需要用户输入,它也应该打开一个模式对话框 - 直到所有条件都通过。

如果只有一个条件需要输入,我没有问题,但如果多个条件需要输入,则只显示第一个模式,我不知道为什么。跟踪代码时,很明显第一个弹出窗口上的 Hide() 被命中,第二个弹出窗口上的 Show() 被命中,但第二个弹出窗口永远不会出现。

我试图以极其简化的方式在这里提取相关的代码块。这是一个非常复杂的项目,我可能遗漏了一些东西,但我希望它足以描述我的问题。

有问题的工艺流程:

  1. 用户单击“继续” -> 调用 DoContinue -> 设置条件标志 -> 显示第一个模式弹出窗口 -> 返回给用户

  2. 用户单击“是”-> 调用条件 1 是单击处理程序(设置已处理标志,隐藏模式弹出窗口)-> 调用 DoContinue-> 重新评估条件标志-> 尝试显示第二个模式弹出窗口-> 返回给用户。

第一个弹出窗口消失,但第二个从未显示。

只有在第二个调用 Show() 的同一请求中的第一个模式上调用 Hide() 时才会出现问题。

MyContainerControl.ascx:

<%@ Control Language="C#" AutoEventWireup="true" Inherits="MyContainerControl" %>
 <input Type="Submit"
          id="btnContinue"
          Name="btnContinue"
          Value="Continue"
          OnServerClick="Continue_Click"
          runat="server"/>

<asp:UpdatePanel 
        ID="updateCondition1" 
        runat="server" 
        ChildrenAsTriggers="false" UpdateMode="Conditional">
    <ContentTemplate>
        <ajaxToolkit:ModalPopupExtender 
                    ID="modalCondition1" 
                    runat="server" 
                    BehaviorID="dlgCondition1"
                    TargetControlID="btnFakeInvokeModalCondition1" 
                    PopupControlID="divCondition1" 
                    BackgroundCssClass="modalBackground"
                    DropShadow="true" 
                    PopupDragHandleControlID="divDragCondition1"
                    RepositionMode="RepositionOnWindowResize" 
                    CancelControlID="btnCondition1No" />
        <input type="button" 
                        id="btnFakeInvokeModalCondition1" 
                        runat="server" 
                        style="display: none" />
        <div id="divCondition1" 
                runat="server" 
                class="modalPopup">
            <custom:Condition1Control id="condition1" runat="server" visible="false" />
            <div id="divDragCondition1"></div>
        </div>
    </ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel 
        ID="updateCondition2" 
        runat="server" 
        ChildrenAsTriggers="false" UpdateMode="Conditional">
    <ContentTemplate>
        <ajaxToolkit:ModalPopupExtender 
                    ID="modalCondition2" 
                    runat="server" 
                    BehaviorID="dlgCondition2"
                    TargetControlID="btnFakeInvokeModalCondition2" 
                    PopupControlID="divCondition2" 
                    BackgroundCssClass="modalBackground"
                    DropShadow="true" 
                    PopupDragHandleControlID="divDragCondition2"
                    RepositionMode="RepositionOnWindowResize" 
                    CancelControlID="btnCondition2No" />
        <input type="button" 
                        id="btnFakeInvokeModalCondition2" 
                        runat="server" 
                        style="display: none" />
        <div id="divCondition2" 
                runat="server" 
                class="modalPopup">
            <custom:Condition2Control id="condition2" runat="server" visible="false" />
            <div id="divDragCondition2"></div>
        </div>
    </ContentTemplate>
</asp:UpdatePanel>

MyContainerControl.cs:

public class MyContainerControl : System.Web.UI.UserControl
{
    protected HtmlInputImage btnContinue;

    //Condition1
    protected AjaxControlToolkit.ModalPopupExtender modalCondition1;
    protected UpdatePanel updateCondition1;
    protected HtmlGenericControl divCondition1;
    protected Condition1Control condition1;

    //Condition2
    protected AjaxControlToolkit.ModalPopupExtender modalCondition2;
    protected UpdatePanel updateCondition2;
    protected HtmlGenericControl divCondition2;
    protected Condition2Control condition2;        

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        condition1.Condition1RaisedEvent += HandleCondition1Event;
        condition2.Condition2RaisedEvent += HandleCondition2Event;
        btnContinue.ServerClick += btnContinue_ServerClick;
    }

    protected void HandleCondition1Event(object sender, Condition1EventArgs e)
    {
        // use ship to store
        ViewState["Condition1Yes"] = true;
        ViewState["Condition1Value"] = e.Condition1Value;
        modalCondition1.Hide();
        DoContinue(sender);
    }

    protected void HandleCondition2Event(object sender, Condition2EventArgs e)
    {
        // use ship to store
        ViewState["Condition2Yes"] = true;
        ViewState["Condition2Value"] = e.Condition2Value;
        modalCondition2.Hide();
        DoContinue(sender);
    }

    protected void btnContinue_ServerClick(object sender, EventArgs e)
    {
        DoContinue(sender);
    }

    protected void DoContinue(object sender)
    {
        // test for conditions - just plug to true for demonstration

        bool throwCondition1 !(ViewState["Condition1Yes"] == null ? false : (bool)ViewState["Condition1Yes"])
        bool throwCondition2 = !(ViewState["Condition2Yes"] == null ? false : (bool)ViewState["Condition2Yes"])

        // analyze conditions

        if (throwCondition1)
        {
            var condition1Yes = ViewState["Condition1Yes"] == null ? false : (bool)ViewState["Condition1Yes"];
            if (!condition1Yes)
            {
                divCondition1.Visible = true;
                modalCondition1.Show();
                return;
            }
        }

        if (throwCondition2)
        {
            var condition2Yes = ViewState["Condition2Yes"] == null ? false : (bool)ViewState["Condition2Yes"];
            if (!condition2Yes)
            {
                divCondition2.Visible = true;
                modalCondition1.Show();
                return;
            }
        }

        // do other work
    }
}

Condition1UI.ascx - Condition2UI.ascx 非常相似:

<%@ Control Language="C#" AutoEventWireup="true" Inherits="Condition1Control" %>
<div id="divCondition1Container" runat="server">        
    <input id="hdnCondition1Value" type="hidden" runat="server" value="<%# this.Condition1Value %>" />
    <asp:Panel ID="pnlCondition1UI" runat="server">
        <br />
        <h2>
            Warning!</h2>
        <hr />
        <br />
        <div>
            <p>Condition1 has been met.</p>
            <br />
            <br />
            <p>Would you like to continue?</p>
        </div>
        <br />
        <br />
    </asp:Panel>
    <div>
    <table>
        <tr>
            <td align="center">
                <asp:Button ID="btnCondition1Yes" runat="server" class="green" Text="Yes" style="padding: 3px 7px;" OnClick="DoCondition1YesClick" OnClientClick="$find('dlgCondition1').hide();" />
            </td>
            <td align="center">
                <button id="btnCondition1No" class="red">No</button>
            </td>
        </tr>
    </table>
      <br />
    </div>
    <br />
</div>

Condition1Control.cs - Condition2Control.cs 几乎相同:

public class Condition1EventArgs : EventArgs
{
    public string Condition1Value { get; set; }
}

public class Condition1Control : System.Web.UI.UserControl
{
    public HtmlInputHidden Condition1Value;

    public event EventHandler<Condition1EventArgs> Condition1RaisedEvent;

    protected virtual void RaiseCondition1Event(Condition1EventArgs e)
    {
        EventHandler<Condition1EventArgs> handler = Condition1RaisedEvent;

        if (handler == null)
        {
            return;
        }

        handler(this, e);
    }

    public void DoCondition1ButtonYesClick(object sender, EventArgs e)
    {
        RaiseCondition1Event(new Condition1EventArgs{
            Condition1Value = Condition1Value.Value
        });
    }
}
4

1 回答 1

2

将 UpdatePanel 的 UpdateMode 属性更改为“Always”,或者不要忘记调用 UpdatePanel 的“Update”方法,因为从另一个 UpdatePanel 触发回发,您要更新哪个 UI。因此,请尝试在代码中的 modalCondition2.Show 方法之后添加 updateCondition2.Update 方法调用。

于 2012-08-13T20:08:51.140 回答