Button添加事件委托问题

lisweden 2011-08-30 03:29:48
页面上有一个Button和一个UpdatePanel,为什么需要点击两次Button,UpdatePanel才更新,而不是点击一次. 代码如下,帮帮忙解决.



protected void Page_Load(object sender, EventArgs e)
{
this.bt.Click += new EventHandler(PanelUpdate); //添加事件委托
}

void PanelUpdate(object sender, EventArgs e)
{
this.UpdatePanel1.Update();
}

protected void bt_Click(object sender, EventArgs e) //Button点击事件
{
...... ///一些代码

}

...全文
460 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
Moqin89 2012-09-03
  • 打赏
  • 举报
回复
有点启发性
lisweden 2011-08-31
  • 打赏
  • 举报
回复
问题解决了(其实和之前的贴一样)!!首先,因为没有对问题的正确描述,就让大家没有针对性地去解决问题,感到非常抱歉.其次,非常感谢sp1234 大牛人,问题的解决主要是得到了他的帮助,还有他的一些建议.对自定义控件注册行为接口不了解,所以就想当通过FillControl来对Button通过添加事件委托来实现需求.这样的去解决问题,通常是菜鸟程序员犯的错(比如我),没有从设计原则和面向对象的思想入手去解决问题.真是受教了!!
gengchenhui 2011-08-30
  • 打赏
  • 举报
回复
wslxxd。。。
  • 打赏
  • 举报
回复
顺便说其它的两个问题(但是与你的这个测试出来的bug没有直接关系)。

首先是“合同、接口”的独立性问题。比如你的Header既然是一个控件,别的程序想当然地去FindControl("search")控件这就不能视为靠谱的行为。因为控件会随时重构,说不定这个按钮会放到一个FormView里边去,甚至根本没有Button而是使用一个动画图片(例如倒计时秒表)。所以行为要靠接口来规范,Header.ascx公开了的接口行为,例如当关注的数据修改了时要抛一个事件通知,而Header.ascx完全不必公开什么Button.Click事件。搞清楚接口这是比随后写代码实现更加重要的事情,也就是说调用者只应该按照接口来调用,而不能想当然地假设控件里边是怎么实现的(否则就妨害了控件的重构)。

第二就是个问题就是使用Session集合。最好不要使用Session集合,因为它是会话范畴的。可能你没有做过复杂的程序,复杂一点的程序会有很多控件实例以各种可能次序运行着,甚至并发运行着(比如说浏览器端同一个页面上有图片、脚本、ajax、iframe等等,或者用户就是按Ctrl+N复制了两个页面,或者其它快速操作)。是对象自己的数据就应该自己保管,不要用容易相互冲突而混乱的全局变量来保管。这可能有两种选择:

一种是去修改事件,让它通知客户程序的时候带上数据:
public partial class Header : System.Web.UI.UserControl
{
public event Action<string> CodeSession_Changed;

protected void search_Click(object sender, EventArgs e)
{
if (!this.TextBox1.Text.Equals(""))
{
if (this.CodeSession_Changed != null)
this.CodeSession_Changed(this.TextBox1.Text);
}
}
}

另一种(可能更好,因为不会修改原来的测试用例)方式是在对外接口上增加一个属性来暴露其文本值
public partial class Header : System.Web.UI.UserControl
{
public event Action CodeSession_Changed;

protected void search_Click(object sender, EventArgs e)
{
if (!this.TextBox1.Text.Equals(""))
{
if (this.CodeSession_Changed != null)
this.CodeSession_Changed();
}
}

public string Text
{
get
{
EnsureChildControls();
return this.TextBox1.Text;
}
}
}

这样,通过接口来有限地规定客户程序可以访问的内容,而不需要它想当然地去假设内部就一定是TextBox1实现的(你后肯定会需要对TextBox重构,因为只有不断重构才能提高其商业价值)。

那么当然在session_changed方法中也是相应地作出修改,或者从方法参数或者去访问Text属性,然后传递给RefreshLiteral方法,而content.ascx中也再也不应该依赖于Session集合,而是
public partial class content : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
RefreshLiteral(null);
}

public void RefreshLiteral(string str)
{
if (str == null)
this.Literal1.Text = "Session 为空";
else
this.Literal1.Text = str;
}
}



这里我强调两点,第一点是重视接口设计,避免想当然地去FindControl,考虑最基本的重构、分层的规范。第二点是正确使用会话范畴的Session集合,对象自己的数据应该由对象自己来传递。
  • 打赏
  • 举报
回复
其它问题先不说了,单就这个“刷新”的问题,我对你的代码做了一点修改。

首先对于Header.ascx.cs,我增加了两条代码,目的是抛出事件通知:
public partial class Header : System.Web.UI.UserControl
{
public event Action CodeSession_Changed;

protected void search_Click(object sender, EventArgs e)
{
if (!this.TextBox1.Text.Equals(""))
{
Session["code"] = this.TextBox1.Text;
if (this.CodeSession_Changed != null)
this.CodeSession_Changed();
}
}
}
这样当你修改了Session集合中的数据之后,就可以通知其它程序继续处理。

然后是修改你的content.ascx.cs,使得它刷新Literal控件的行为可以被单独调用:
public partial class content : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
RefreshLiteral();
}

public void RefreshLiteral()
{
if (Session["code"] == null)
this.Literal1.Text = "Session 为空";
else
this.Literal1.Text = Session["code"].ToString();
}
}


然后Build(可以按组合键 Ctrl+Shift+B键),再转在 Demo.aspx 上你就可以在用户控件 Header 上看到事件提示,这是可以增加一个事件处理声明
<uc1:Header ID="Header1" runat="server" OnCodeSession_Changed="session_changed" />


最后当然就要在Demo.aspx.cs实现这个事件处理方法,最终把以上所有东西“粘接”起来:
    protected void session_changed()
{
content1.RefreshLiteral();
}


  • 打赏
  • 举报
回复
[Quote=引用 18 楼 lisweden 的回复:]
做了个DEMO,帮看一下
DEMO
[/Quote]

唉,你没有说清楚你的程序流程。

你使用了Session集合来在不同的ascx中传递数据,但是content.ascx中刷新显示是在page_load中,而header.ascx中修改它是在search_click中,前者先执行,后者才执行。
lisweden 2011-08-30
  • 打赏
  • 举报
回复
下班了,还得买菜.大家帮看下,帮忙解决这个问题!谢谢
LQ_651119244 2011-08-30
  • 打赏
  • 举报
回复
第一次注册事件,第二次才会触发事件 !
lisweden 2011-08-30
  • 打赏
  • 举报
回复
同样需要点击两次Button,UpdatePanel才更新
lisweden 2011-08-30
  • 打赏
  • 举报
回复
做了个DEMO,帮看一下
DEMO
phoebuswei 2011-08-30
  • 打赏
  • 举报
回复

protected void bt_Click(object sender, EventArgs e) //Button点击事件
{
...... ///一些代码
this.UpdatePanel1.Update();

}
萧炎 2011-08-30
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 a82344626 的回复:]
protected void Page_Load(object sender, EventArgs e)
{
this.bt.Click += new EventHandler(PanelUpdate); //添加事件委托
}

这里加个 if(IsPostBack)看下!
因为你一提交页面又重新加方法了!
[/Quote]
--! 正准备说了 被这位兄台抢先了
萧炎 2011-08-30
  • 打赏
  • 举报
回复
LZ看了你的问题 要点击两次 意思就是点第二次才调用到委托
a82344626 2011-08-30
  • 打赏
  • 举报
回复
protected void Page_Load(object sender, EventArgs e)
{
this.bt.Click += new EventHandler(PanelUpdate); //添加事件委托
}

这里加个 if(IsPostBack)看下!
因为你一提交页面又重新加方法了!
  • 打赏
  • 举报
回复
既然只有这么几行代码,你不妨写个demo程序出来,重现你的问题。
lisweden 2011-08-30
  • 打赏
  • 举报
回复
把委托去掉,采用trigger,还是需要点击两下Button,我就郁闷了!!!



<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="bt" EventName="Click" />
</Triggers>
<ContentTemplate>
<asp:Literal ID="Literal1"runat="server" Text="<%$Resources:SharedResources, SiteTitle%>" />
</ContentTemplate>
</asp:UpdatePanel>

C5662601 2011-08-30
  • 打赏
  • 举报
回复
UpdatePanel的UpdateModel修改下属性 试试
lisweden 2011-08-30
  • 打赏
  • 举报
回复
回子夜

...... ///一些代码 之所以不和this.UpdatePanel1.Update();放到一个函数里,是其他的功能要调用void PanelUpdate(object sender, EventArgs e)方法

回8楼:

PanelUpdate这个方法体是进去的,第一次进去后,this.UpdatePanel1.Update();没起作用,第二次进入到,才起作用
ruanwei1987 2011-08-30
  • 打赏
  • 举报
回复

调试下看 点击第一下 进没进入 PanelUpdate这个方法体中
如果没进入 说明第一次点击的 没响应 button事件
子夜__ 2011-08-30
  • 打赏
  • 举报
回复
...... ///一些代码
放到void PanelUpdate(object sender, EventArgs e)
{
this.UpdatePanel1.Update();
}
这个里
加载更多回复(7)

62,047

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧