重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
c#中怎么实现事件双向传值,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
目前创新互联已为上千家的企业提供了网站建设、域名、雅安服务器托管、成都网站托管、企业网站设计、普洱网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MsgMonitor { public delegate int dataProcessDelegate(string msg); //以便子控件和主控件都要使用的委托 public delegate int msgMonitorDelegate(object sender,MsgMonitorEventArgs args);//声明一个delegate public class MsgMonitorCls { public event msgMonitorDelegate OnmsgMonitorEvent;//事件声明及定义 public event EventHandler OnmsgEventHandler; //事件定义时需要在event后面指定委托 //以委托/事件方式传值方式,娄托和事件声明都只在MsgMonitorCls类中出现,即委托,事件只在声明时所在的类中出现, //在发布者和订阅者类中都不会出现委托和事件,只是在发布者中会出现本类实例.事件 += 订阅者对象.和委托有相同签名的函数 //然后,在发布者中当有必要引发事件时,就会调用本类实例.引发事件的函数即可自动发布事件处理。 //public delegate void EventHandler (object sender,TEventArgs args);带有object和TEventArgs参数的委托 public int raisemsgevent(object obj,string msg) //这个函数引发事件 那什么时候调用"引发事件"这个函数呢???? { MsgMonitorEventArgs args = new MsgMonitorEventArgs(msg); if(OnmsgMonitorEvent != null) { if (OnmsgEventHandler != null) { OnmsgEventHandler(obj, args); Console.WriteLine("MsgMonitor EventHandler MsgMonitorEventArgs.retmsg=" + args.retmsg); } int r= OnmsgMonitorEvent(obj, args); Console.WriteLine("MsgMonitor MsgMonitorEventArgs.retmsg="+args.retmsg); return r; } return -1; } } public class MsgMonitorEventArgs:EventArgs { public string msg{get;set;} public string retmsg { get; set; } public MsgMonitorEventArgs(string msg) { this.msg = msg; } } } using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using MsgMonitor; namespace MyFormUIControl { public partial class UserControl1: UserControl { public delegate int dispinfoDelegate(string msg); public event dataProcessDelegate OndataProcessDelegate; public UserControl1() { InitializeComponent(); } public int dataprocess(string msg) { Console.WriteLine("UserControl1 dataprocess "); if (string.IsNullOrEmpty(msg)) { return -11; } if (msg == lblinfo.Text) { return 11; } else { return -11; } } private void btnstart_Click(object sender, EventArgs e) { lblinfo.Text = "btnstart_Click"; if (OndataProcessDelegate != null) OndataProcessDelegate(textBox1.Text); } private void btnstop_Click(object sender, EventArgs e) { lblinfo.Text = "btnstop_Click"; if (OndataProcessDelegate != null) OndataProcessDelegate(textBox1.Text); } public void dispinfo(string msg) { lblinfo.Text = msg; } //子控件中需要有一个与msgMonitorDelegate 委托签名相同的函数 public int msgmonitorfun(object sender,MsgMonitorEventArgs args) { Control ctrl = sender as Control; if(ctrl != null) { Console.WriteLine("msgmonitorfun sender is " + ctrl.Name); } if (string.IsNullOrEmpty(args.msg)) { args.retmsg = "msg null"; return -1; } if (args.msg == lblinfo.Text) { args.retmsg = "msg same"; return 1; } else { args.retmsg = "msg no same"; return -1; } } public void eventhandlerfun(object sender, MsgMonitorEventArgs args) { Control ctrl = sender as Control; if (ctrl != null) { Console.WriteLine("eventhandlerfun sender is " + ctrl.Name); } if (string.IsNullOrEmpty(args.msg)) { args.retmsg = "msg null"; } if (args.msg == lblinfo.Text) { args.retmsg = "msg same"; } else { args.retmsg = "msg no same"; } } } } using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using MsgMonitor; namespace userformcontroldemo { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private MsgMonitorCls msgMonitor; public event dataProcessDelegate OndataProcessDelegate; private void btndispmain_Click(object sender, EventArgs e) { } private void Form1_Load(object sender, EventArgs e) { if(msgMonitor == null) msgMonitor = new MsgMonitorCls(); //事件定义相关的类A有了,A中声明的事件B及事件相应的委托C也有了,与事件相应的委托有相同签名的目的类(即客户类)中的函数D也有了 //将客户类实例E的与事件相应的委托具有相同签名的函数D添加到事件B中 msgMonitor.OnmsgMonitorEvent += userControl11.msgmonitorfun;// new msgMonitorDelegate (userControl11.msgmonitorfun); msgMonitor.OnmsgEventHandler += userControl11.eventhandlerfun;// new EventHandler (userControl11.eventhandlerfun); userControl11.OndataProcessDelegate += new dataProcessDelegate((msg) => { if (msg == "abc") { Console.WriteLine("datarecvvaluefun msg=" + msg + ":return 10"); return 10; } Console.WriteLine("datarecvvaluefun msg=" + msg + ":return -1"); return -1; }); OndataProcessDelegate += new dataProcessDelegate(userControl11.dataprocess); } private int datarecvvaluefun(string msg) { if (msg == "abc") { Console.WriteLine("datarecvvaluefun msg=" + msg + ":return 10"); return 10; } Console.WriteLine("datarecvvaluefun msg=" + msg + ":return -1"); return -1; } private void textBox1_TextChanged(object sender, EventArgs e) { //int res = 0; ////什么时候调用“引发事件函数”呢?应该由发起者调用“引发事件函数”, 客户类即订阅者中的函数D就被自动调用 ////if (msgMonitor.msgMonitorEvent != null) 事件msgMonitorEvent只能出现在+=或-=的左边 //res = msgMonitor.raisemsgevent(this, textBox1.Text);//引发事件函数 被调用,真正的事件签名中对应的函数参数有可能与引发事件函数参数不同 ////所以,事件调用之后有可能被客户类在事件参数中修改的值在此处无法获知,只能在事件定义所有的类中才能获取。假设事件引发函数的参数与事件声明 ////时的参数相同的话,此处确实可以获取客户修改之后的值,但有一个问题:如果事件被+=了多次,也就是说有多个客户订阅了这个事件,最终多个订阅者 ////执行时各个不同的订阅者修改的值不一致,导致此处的调用引发事件函数之后的取值并没有意义。 ////那么要想在此处获得订阅者执行之后的值,应该人为规定:只能有一个订阅者,从语法角度来说需要引发事件函数的参数与事件对应的委托的参数类型相同 //Console.WriteLine("raisemsgevent return value=" + res); } private void button1_Click(object sender, EventArgs e) { if(OndataProcessDelegate != null) { int r = OndataProcessDelegate(textBox1.Text); Console.WriteLine("button1_Click OndataProcessDelegate r=" + r); } } } }
看完上述内容,你们掌握c#中怎么实现事件双向传值的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!