这已经让我发疯了2天了-希望以前有人看到过。
我有一个问题,即在中继器或网格视图中控件的第一次单击无法激发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);
}
}
我想知道这是否是viewstate问题,以及在哪些页面事件中应该使用DataBind()。我已经在不同的页面事件中尝试了数据绑定,从而启用了页面上的viewstate和控件,而结果没有变化。
这是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>
一些可能相关的进一步信息:
我注意到在usercontrol的Page_Load事件中是我重新绑定控件的地方。这可能是因为控件状态被重写而引起的原因,但是如果我在ascx的该区域添加if(!IsPostback),则此代码段根本不会像在aspx页面上那样触发。那将是重新绑定控件的正确部分,我认为。
最佳答案
MikeW,
经过数小时的摆弄,我找到了问题的根源。
它与中继器或gridview无关。
这只是一个动态控制回发问题。
解决您的问题:
令人惊讶的是,您的代码中仅缺少一行。
在您加载控件时,请为它的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(这相当于您在两个不同的动态控件之间进行大小写切换)。
猜猜现在会发生什么:
Page_Load
将从ViewState
加载Button2。在清除占位符后,Button1的Click
事件将加载另一个Button2实例。由于您没有为其分配ID,因此它将在
UniqueID
中为其分配一个ID,而这两个Button2将具有类似ctl02和ctl03的名称。现在单击Button2。
您会说“很好,我们正在覆盖旧的”。是的,但不是没有ID。
由于您没有在回发中给它提供ID来标识它,因此它将使用
UniqueID
,它是按顺序生成的。现在,该页面正在查找ctl03(该目录不存在),因此不会触发
Click
。但是,到目前为止,我们有了一个全新的Button2,其
UniqueID
ctl02。单击此新的Button2可以正常工作,在回发上,因为它是唯一的Button2,所以它恰好具有ctl02的
UniqueID
。那么,分配ID如何使其起作用?
这样,每个生成的新控件都将具有相同的ID,因此在回发时,无论是在
Page_Load
还是在另一个按钮的Click
事件中生成的,它都可以找到所需的内容。希望能解释为什么它起作用,但是就您而言,只需为其分配一个ID,一切都会好起来的。
我认为分享其背后的机制以及为什么会这样很有趣。 =)
关于c# - 第一次单击Repeater或GridView时未触发ItemCommand,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4034644/