这两天已经让我发疯了——希望有人以前见过这个。
我遇到这样的问题:第一次单击中继器或网格视图中的控件无法触发 ItemCommand 事件,但所有后续单击都有效。控件被加载到 Base.aspx 上的占位符中,如下所示
private void LoadUserControl()
{
string controlPath = LastLoadedControl;
if (!string.IsNullOrEmpty(controlPath))
{
ph.Controls.Clear();
UserControl uc = (UserControl)LoadControl(controlPath);
ph.Controls.Add(uc);
}
}
我想知道这是否是一个视图状态问题,以及在哪些页面事件中我应该使用 DataBind()。我在不同的页面事件中尝试了数据绑定,在页面上启用视图状态并进行控制,而不会改变结果。
这是 GridView 模板,但我对转发器控件也有相同的行为,所以我不相信它是这个问题的控件。
<ItemTemplate>
<asp:RadioButton ID="rbEnable" GroupName="MyGroup" runat="server" Text="Enabled" Checked="<%# ((EducateMe.BaseTypes.AbstractLink)Container.DataItem).IsActive == true %>" />
<asp:RadioButton ID="rbDisable" runat="server" GroupName="MyGroup" Text="Disabled" Checked="<%# ((EducateMe.BaseTypes.AbstractLink)Container.DataItem).IsActive != true %>" />
<asp:Button ID="btnEnable" runat="server" CommandArgument="<% # Container.DataItemIndex %>" CommandName="Enable" ToolTip="Enable" Text="Save" />
<asp:Button ID="btnDisable" runat="server" CommandArgument="<% # Container.DataItemIndex %>" Visible="false" CommandName="Disable" ToolTip="Disable" Text="Disable" />
</ItemTemplate>
一些可能相关的进一步信息:
我注意到用户控件的 Page_Load 事件是我重新绑定控件的地方。这可能是控件状态被重写的原因,但如果我将 if(!IsPostback) 添加到 ascx 中的此区域,则此代码部分根本不会像在 aspx 页面上那样触发。我认为这将是重新绑定控件的正确部分。
MikeW,
经过几个小时的摆弄,我找到了问题的根源。
它与中继器或网格视图没有什么特别的关系。
这只是一个回发动态控制问题。
为了解决您的问题:
令人惊讶的是,您的代码中只缺少一行。
当您加载控件时,为其 ID 分配一些内容,如下所示:
UserControl uc = (UserControl)LoadControl(controlPath);
uc.ID = "mycontrol";
ph.Controls.Add(uc);
这样,当您回发时,页面就知道哪个控件是哪个。
为了更容易地解释这一点,让我们简化问题。
以下是连续单击一个按钮两次动态创建另一个按钮的场景:
- 创建一个按钮 Button1,单击该按钮时将动态加载另一个按钮 Button2。假设 Button2 的操作就像显示当前时间一样简单。
- 现在,单击 Button1。
- 要保留 Button2,您必须使用
ViewState
告诉页面有一个动态控件。就像您所做的那样,我们可以记住控件的路径或其类的名称。
- 当页面回发时,在
Page_Load
,我们看ViewState
看到有一个我们试图保留的控件,所以我们就在那里加载它(这相当于你的LoadUserControl()
函数如上)。
- 现在,Button2 是可见的,当单击时,它会很好地执行其操作。
- 不要点击Button2,只需再次点击Button1(相当于你的case在两个不同的动态控件之间切换)。
- 猜猜现在会发生什么:
Page_Load
将从中加载 Button2ViewState
。还有Click
清除占位符后,Button1 的事件将加载另一个 Button2 实例。
- 由于您没有为其分配 ID,因此它会为自己分配一个 ID
UniqueID
,这两个 Button2 将具有类似的内容ctl02 and ctl03
- 现在单击按钮2。
- 你会说“没关系,我们正在覆盖旧的”。可以,但是没有身份证就不行。
- 由于您没有给它一个 ID 来在回发时识别它,因此它将利用
UniqueID
,依次生成。
- 现在页面正在寻找ctl03,它不存在,所以
Click
不着火。
- 但是,现在我们有了一个全新的 Button2,其中
UniqueID
ctl02.
- 单击这个新的 Button2 就可以正常工作,因为在回发时,它是唯一的 Button2,因此它碰巧会有一个
UniqueID
of ctl02.
那么,分配 ID 是如何使其发挥作用的呢?
这样,生成的每个新控件都将具有相同的 ID,因此在回发时,它可以找到它要查找的内容,无论它是否是在Page_Load
或者在另一个按钮上Click
事件。
希望这能解释它为什么起作用,但只要你关心,只要给它分配一个 ID,一切都会好起来的。
我认为分享其背后的机制以及原因会很有趣。 =)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)