温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

c#中怎么实现事件双向传值

发布时间:2021-06-22 16:22:02 来源:亿速云 阅读:208 作者:Leah 栏目:编程语言

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#中怎么实现事件双向传值的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI