• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

c#事件双向传值实验

互联网 diligentman 1周前 (04-08) 3次浏览
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);
            }
        }
    }
}

 

展开阅读全文

© 著作权归作者所有

举报

打赏

0


0 收藏

微信
QQ
微博

分享

作者的其它热门文章

Spring AOP拦截抽象类(父类)中方法失效问题
NPOI使用手册
ILA调试报错 The debug hub core was not detected 以及 Data read from hw_ila [hw_ila_1] is corrupted…
NDK字符串处理GetStringUTFChars


程序员灯塔
转载请注明原文链接:c#事件双向传值实验
喜欢 (0)