我在同一服务器端调用中隐藏一个 ModalPopupExtender 并显示另一个时遇到问题。
我的应用程序需要用户输入某些验证条件。这些条件按顺序进行评估,当某些条件为真时,需要用户通过 ModalPopupExtender 窗口进行验证(单击是或否)。如果用户单击是,评估应该继续,如果另一个条件需要用户输入,它也应该打开一个模式对话框 - 直到所有条件都通过。
如果只有一个条件需要输入,我没有问题,但如果多个条件需要输入,则只显示第一个模式,我不知道为什么。跟踪代码时,很明显第一个弹出窗口上的 Hide() 被命中,第二个弹出窗口上的 Show() 被命中,但第二个弹出窗口永远不会出现。
我试图以极其简化的方式在这里提取相关的代码块。这是一个非常复杂的项目,我可能遗漏了一些东西,但我希望它足以描述我的问题。
有问题的工艺流程:
用户单击“继续” -> 调用 DoContinue -> 设置条件标志 -> 显示第一个模式弹出窗口 -> 返回给用户
用户单击“是”-> 调用条件 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
});
}
}