您好,登錄后才能下訂單哦!
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<MsgMonitorEventArgs>(object sender,MsgMonitorEventArgs args);//聲明一個delegate public class MsgMonitorCls { public event msgMonitorDelegate<MsgMonitorEventArgs> OnmsgMonitorEvent;//事件聲明及定義 public event EventHandler<MsgMonitorEventArgs> OnmsgEventHandler; //事件定義時需要在event后面指定委托 //以委托/事件方式傳值方式,婁托和事件聲明都只在MsgMonitorCls類中出現,即委托,事件只在聲明時所在的類中出現, //在發布者和訂閱者類中都不會出現委托和事件,只是在發布者中會出現本類實例.事件 += 訂閱者對象.和委托有相同簽名的函數 //然后,在發布者中當有必要引發事件時,就會調用本類實例.引發事件的函數即可自動發布事件處理。 //public delegate void EventHandler<TEventArgs>(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<MsgMonitorEventArgs>委托簽名相同的函數 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<MsgMonitorEventArgs>(userControl11.msgmonitorfun); msgMonitor.OnmsgEventHandler += userControl11.eventhandlerfun;// new EventHandler<MsgMonitorEventArgs>(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#中怎么實現事件雙向傳值的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。