我有一个问题,我无法理解在这个设置中,我失去了捕捉PostBack触发器的能力,或者仅仅是serverclick的处理程序方法,并且放置断点只显示PostBack发生在渲染(Page_Load)时,而不是在单击提交按钮后。请允许我详细说明这个场景,并记住,我改变它的方式的能力有限,必须想办法让它在每个客户端使用ASP.net/C#/WebForms/Bootstrap 4.5进行微小的更改。
Dashboard.aspx
[主页]有一个简单的(顶部导航显示徽标和登录用户名,带有注销下拉菜单,侧边栏菜单,单击后将加载到显示区域),显示区域是asp:PlaceHolder
元素:
<asp:PlaceHolder runat="server" ClientIDMode="Static" ID="TheScreen">
当加载[主页]时,它会调用API并处理接收到的对象集合,并生成添加一系列UserControlControl1
对象(这可以是零项或n项)。让我们调用登录的[默认状态],以便我们稍后可以引用它。
每个Control1
(具有唯一的ID)具有3个按钮来执行3个不同的动作。
<a class="btn btn-primary btn-sm" id="action1" runat="server" onserverclick="Command_Click">Do First Action</a>
<a class="btn btn-primary btn-sm" id="action2" runat="server" onserverclick="Command_Click">Do Second Action</a>
<a class="btn btn-primary btn-sm" id="action3" runat="server" onserverclick="Command_Click">Do Third Action</a>
Command_Click
只是弹出一个要由Dashboard.aspx
处理的事件处理程序
public void Command_Click(object sender, EventArgs e)
{
CommandClicked?.Invoke(sender, e);
}
action1
通过一个确认模式进行动态处理,该模式包含一个运行onserverclick
并使用API调用重新加载已删除该项的[默认状态]的简单按钮。
<button type="button" class="btn" id="do-action1" runat="server" onserverclick="finish-action1">Do It</button>
这一切都如预期的那样。
action2
由[主页]处理,它清除PlaceHolder
的控件,然后动态创建并加载另一个UserControl,该UserControl显示该对象的长格式详细信息。
UControl2 theObject = (UControl2)Page.LoadControl("~/path/to/Control2.ascx");
TheScreen.Controls.Clear();
TheScreen.Controls.Add(theObject);
这一切也正如预期的那样。
action3
按钮是给我带来问题的按钮,就像action2
一样,它在[主页]上处理,在那里它清除PlaceHolder
的控件,然后动态创建和加载另一个UserControl,它提供了一个带有一个按钮的简单表单。
UControl3 otherObject = (UControl3)Page.LoadControl("~/path/to/Control3.ascx");
TheScreen.Controls.Clear();
TheScreen.Controls.Add(otherObject);
表单非常简单,包含一个<select>
元素,其<option>
是使用基于API调用的asp:Repeater
填充的,该调用为其提供DataSource。它还有一个简单的<input>
文本框字段,最后还有一个提交<button>
。
<select id="..." name="..." required="required">
<option disabled selected value="">select payment account</option>
<asp:Repeater ID="..." ClientIDMode="Static" runat="server" ItemType="model.namespace">
<ItemTemplate>
<option value="<%#: Eval("...") %>">
<%#: Eval("...") + " " + Eval("...") %>
</option>
</ItemTemplate>
</asp:Repeater>
</select>
<input id="..." name="..." type="text" required="required" runat="server" />
<button id="finish-action3" class="btn" runat="server" onserverclick="do-action3">Do It</button>
我不明白finish-action3
为什么不执行处理程序方法do-action3
的操作,它只是刷新回[主页],使用我们从初始状态开始的初始状态,初始Control1
正在渲染,没有其他内容,也没有PostBack。
我进行了广泛的搜索,没有发现任何关于这个特定场景的内容,我发现,每个人都在建议使用asp:Button
,但这对我的行为没有任何影响。
如上所述,单击
Control3
中的finish-action3
按钮不会导致基本的HTML5验证,也不会触发do-action3
处理程序方法,只需刷新回我们开始的[主页]。如果我将
do-action3
添加到onsubmit
属性或添加type=submit
,我会得到验证,但一旦它通过验证,同样的行为就是加载[主页面]。将元素更改为
asp:Button
完全没有区别。验证是在没有任何特殊情况下触发的(比如使用onsubmit
属性或具有type=submit
,但一旦验证了相同的行为,就永远不会调用do-action3
,甚至不会在control3
上触发Page_Load/PostBack,只返回到[主页]
我怀疑我忽略了某个事件,或者没有冒泡,在这个过程中迷路了,但我想不出是什么,在哪里,为什么。为什么屏幕上最后一个由CCD_;提交";单击该按钮不生成PostBack
或运行onserverclick
处理程序方法,只需刷新到主默认状态页,我在这里缺少什么?
任何帮助都将不胜感激,因为我一直在用头撞墙,试图弄清楚我错过了什么。我从未在MVC或Core中遇到过这种情况,它让我抓狂。
让我们简化一下。基本上,您所说的是以下内容不起作用,因为动态添加的Control3
用户控件的btnFinishAction3_Click
方法没有启动:
Default.aspx(主页):
<asp:PlaceHolder runat="server" ID="plhPlaceHolder1"></asp:PlaceHolder>
<asp:Button runat="server" ID="btnAction3"
Text="Do Third Action"
OnClick="btnAction3_Click"/>
Default.aspx。cs:
protected void btnAction3_Click(object sender, EventArgs e)
{
AddControl3();
}
private void AddControl3()
{
Control3 objControl3 = (Control3)Page.LoadControl("~/Control3.ascx");
plhPlaceHolder1.Controls.Clear();
plhPlaceHolder1.Controls.Add(objControl3);
}
Control3.ascx:
<asp:Label runat="server" ID="lblMessage"></asp:Label>
<asp:Button runat="server" ID="btnFinishAction3"
Text="Finish Action 3"
OnClick="btnFinishAction3_Click"/>
Control3.ascx.cs:
protected void btnFinishAction3_Click(object sender, EventArgs e)
{
lblMessage.Text = "Finished Action 3.";
}
这是正常行为。在回发之后,动态添加的用户控件不存在;忽略";。在ASP.NET Web窗体中,每次回发后,必须将每个动态控件重新添加到页面中。因此,您需要以下内容:
Default.aspx(主页):
<asp:PlaceHolder runat="server" ID="plhPlaceHolder1"></asp:PlaceHolder>
<asp:HiddenField runat="server" ID="hifControl3Loaded"/>
<asp:Button runat="server" ID="btnAction3"
Text="Do Third Action"
OnClick="btnAction3_Click"/>
Default.aspx。cs:
protected void Page_Load(object sender, EventArgs e)
{
if (hifControl3Loaded.Value == "1")
{
AddControl3();
}
}
protected void btnAction3_Click(object sender, EventArgs e)
{
AddControl3();
hifControl3Loaded.Value = "1";
}
private void AddControl3()
{
Control3 objControl3 = (Control3)Page.LoadControl("~/Control3.ascx");
plhPlaceHolder1.Controls.Clear();
plhPlaceHolder1.Controls.Add(objControl3);
}
换句话说,一旦用户决定首先单击btnAction3
按钮添加Control3
,就需要在Page_Load
上每次回发时将其添加到主页面。