c#中怎么實現(xiàn)事件雙向傳值,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
目前創(chuàng)新互聯(lián)已為上千家的企業(yè)提供了網(wǎng)站建設、域名、雅安服務器托管、成都網(wǎng)站托管、企業(yè)網(wǎng)站設計、普洱網(wǎng)站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
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類中出現(xiàn),即委托,事件只在聲明時所在的類中出現(xiàn), //在發(fā)布者和訂閱者類中都不會出現(xiàn)委托和事件,只是在發(fā)布者中會出現(xiàn)本類實例.事件 += 訂閱者對象.和委托有相同簽名的函數(shù) //然后,在發(fā)布者中當有必要引發(fā)事件時,就會調用本類實例.引發(fā)事件的函數(shù)即可自動發(fā)布事件處理。 //public delegate void EventHandler (object sender,TEventArgs args);帶有object和TEventArgs參數(shù)的委托 public int raisemsgevent(object obj,string msg) //這個函數(shù)引發(fā)事件 那什么時候調用"引發(fā)事件"這個函數(shù)呢???? { 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 委托簽名相同的函數(shù) 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也有了,與事件相應的委托有相同簽名的目的類(即客戶類)中的函數(shù)D也有了 //將客戶類實例E的與事件相應的委托具有相同簽名的函數(shù)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; ////什么時候調用“引發(fā)事件函數(shù)”呢?應該由發(fā)起者調用“引發(fā)事件函數(shù)”, 客戶類即訂閱者中的函數(shù)D就被自動調用 ////if (msgMonitor.msgMonitorEvent != null) 事件msgMonitorEvent只能出現(xiàn)在+=或-=的左邊 //res = msgMonitor.raisemsgevent(this, textBox1.Text);//引發(fā)事件函數(shù) 被調用,真正的事件簽名中對應的函數(shù)參數(shù)有可能與引發(fā)事件函數(shù)參數(shù)不同 ////所以,事件調用之后有可能被客戶類在事件參數(shù)中修改的值在此處無法獲知,只能在事件定義所有的類中才能獲取。假設事件引發(fā)函數(shù)的參數(shù)與事件聲明 ////時的參數(shù)相同的話,此處確實可以獲取客戶修改之后的值,但有一個問題:如果事件被+=了多次,也就是說有多個客戶訂閱了這個事件,最終多個訂閱者 ////執(zhí)行時各個不同的訂閱者修改的值不一致,導致此處的調用引發(fā)事件函數(shù)之后的取值并沒有意義。 ////那么要想在此處獲得訂閱者執(zhí)行之后的值,應該人為規(guī)定:只能有一個訂閱者,從語法角度來說需要引發(fā)事件函數(shù)的參數(shù)與事件對應的委托的參數(shù)類型相同 //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#中怎么實現(xiàn)事件雙向傳值的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!