溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

c#中怎么實現(xiàn)事件雙向傳值

發(fā)布時間:2021-06-22 16:22:02 來源:億速云 閱讀:225 作者:Leah 欄目:編程語言

c#中怎么實現(xiàn)事件雙向傳值,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

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類中出現(xiàn),即委托,事件只在聲明時所在的類中出現(xiàn),
        //在發(fā)布者和訂閱者類中都不會出現(xiàn)委托和事件,只是在發(fā)布者中會出現(xiàn)本類實例.事件 += 訂閱者對象.和委托有相同簽名的函數(shù)
        //然后,在發(fā)布者中當(dāng)有必要引發(fā)事件時,就會調(diào)用本類實例.引發(fā)事件的函數(shù)即可自動發(fā)布事件處理。
        //public delegate void EventHandler<TEventArgs>(object sender,TEventArgs args);帶有object和TEventArgs參數(shù)的委托
        public int raisemsgevent(object obj,string msg) //這個函數(shù)引發(fā)事件 那什么時候調(diào)用"引發(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<MsgMonitorEventArgs>委托簽名相同的函數(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();
            //事件定義相關(guān)的類A有了,A中聲明的事件B及事件相應(yīng)的委托C也有了,與事件相應(yīng)的委托有相同簽名的目的類(即客戶類)中的函數(shù)D也有了
            //將客戶類實例E的與事件相應(yīng)的委托具有相同簽名的函數(shù)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;
            ////什么時候調(diào)用“引發(fā)事件函數(shù)”呢?應(yīng)該由發(fā)起者調(diào)用“引發(fā)事件函數(shù)”, 客戶類即訂閱者中的函數(shù)D就被自動調(diào)用
            ////if (msgMonitor.msgMonitorEvent != null) 事件msgMonitorEvent只能出現(xiàn)在+=或-=的左邊
            //res = msgMonitor.raisemsgevent(this, textBox1.Text);//引發(fā)事件函數(shù) 被調(diào)用,真正的事件簽名中對應(yīng)的函數(shù)參數(shù)有可能與引發(fā)事件函數(shù)參數(shù)不同
            ////所以,事件調(diào)用之后有可能被客戶類在事件參數(shù)中修改的值在此處無法獲知,只能在事件定義所有的類中才能獲取。假設(shè)事件引發(fā)函數(shù)的參數(shù)與事件聲明
            ////時的參數(shù)相同的話,此處確實可以獲取客戶修改之后的值,但有一個問題:如果事件被+=了多次,也就是說有多個客戶訂閱了這個事件,最終多個訂閱者
            ////執(zhí)行時各個不同的訂閱者修改的值不一致,導(dǎo)致此處的調(diào)用引發(fā)事件函數(shù)之后的取值并沒有意義。
            ////那么要想在此處獲得訂閱者執(zhí)行之后的值,應(yīng)該人為規(guī)定:只能有一個訂閱者,從語法角度來說需要引發(fā)事件函數(shù)的參數(shù)與事件對應(yīng)的委托的參數(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);
            }
        }
    }
}

看完上述內(nèi)容,你們掌握c#中怎么實現(xiàn)事件雙向傳值的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI