趁着1024这个好日子来讲一下
通常在C# 中
为了将功能模块化
我们会把重复使用的功能写到类 (Class)里面
但是写在类里面的方法是无法直接对主窗体界面进行操作的
这个时候我们就需要使用 “委托”
关于委托的讲解可以参考这篇
https://www.cnblogs.com/wudiwushen/archive/2010/04/20/1703368.html
讲的挺浅显易懂的
但随着时代的进步
程式语言也在进步(人越来越懒)
现在我们只需要在类中声明一个Event Action的变量
就可以让随时呼叫并执行我们在主界面的方法
而主界面的方法就可以对界面进行操作拉
类
class Class1
{
public event Action Call; <--记得要用public才找得到
public void Show()
{
Call.Invoke();
}
}
Form1
public partial class Form1 : Form
{
Class1 c1;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
c1 = new Class1();
c1.Call += Called; <---注意这里
}
private void Called()
{
label1.Text = "123";
}
private void button1_Click(object sender, EventArgs e)
{
c1.Show(); <--会在Show里面invoke到Called
}
}
Form1中+=使用的就是一个委托的概念
意思是当c1 这个object(类的实例化)里面的Call (呼叫)这个Event Action的时候
会呼叫到Form1 (主界面)中的Called (被呼叫)方法
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191024104216469.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191024104224958.png)
这个时候的顺序应该是
- 按下button1
- 执行c1.show()
- show方法中执行Call.Invoke()
- Call.Invoke()呼叫Called方法执行 (因为 c1.Call += Called这句)
- 执行Called方法
- 将Label1的文字修改为 “123”
那么若是
多了一个button里头执行
private void button2_Click(object sender, EventArgs e)
{
c1.Call -= Called;
}
会发生什么事?
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191024105244773.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0dUV0xpbg==,size_16,color_FFFFFF,t_70)
我们再理清一下顺序
- 按下button1
- 执行c1.show()
- show方法中执行Call.Invoke()
- Call.Invoke()呼叫Called方法执行 (因为 c1.Call += Called这句)
- 执行Called方法
- 将Label1的文字修改为 “123”
--------到这边位置都一样-------- - 按下button2 (c1.Call -= Called 取消注册)
- 按下button1
- 执行c1.show()
- show方法中执行Call.Invoke()
- 因为Call并没有注册任何的方法,系统不知道要呼叫谁就报错了
那有没有方法避免呢? 是有的
public void Show()
{
Call?.Invoke();
}
看得出来差在哪里吗?
其实就只加了一个?上去而已
但这个问号在的功用等于
if (Call != null) { Call.invoke();}
因为Call并未注册 (被取消注册) 所以没有任何值或地址在里面
所以便不会执行Call.Invoke()了
再来 如果我们要将变量透过invoke()传递该怎么做呢?
很简单
类
public event Action<string> Call; <--代表呼叫接收一个string的方法
public void Show()
{
string text = "456";
Call?.Invoke(text);
}
Form1
Class1 c1;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
c1 = new Class1();
c1.Call += Called;
}
private void Called(string text) <--接收一个string
{
label1.Text = text;
}
private void button1_Click(object sender, EventArgs e)
{
c1.Show();
}
private void button2_Click(object sender, EventArgs e)
{
c1.Call -= Called;
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191024111304972.png)
当然 你也可以不只传递一个参数
public event Action<int, string, string> Call;
public void Show()
{
int time = 2;
string text1 = "456";
string text2 = "789";
Call?.Invoke(time, text1, text2);
}
Class1 c1;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
c1 = new Class1();
c1.Call += Called;
}
private void Called(int time, string text1, string text2)
{
for(int i=0; i<time; i++)
{
label1.Text += text1;
label1.Text += text2;
label1.Text += "x";
}
}
private void button1_Click(object sender, EventArgs e)
{
c1.Show();
}
private void button2_Click(object sender, EventArgs e)
{
c1.Call -= Called;
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191024111907525.png)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)