Fork me on GitHub

c#笔记:对象间数据传递

C#学习笔记
对象间数据的传递和回调
以windowsForm程序为例

主窗口向从窗口传递数据

运行示例

设置一个公有属性或设置公有方法来实现

主窗体代码:

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MainToOther
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private FormOther otherForm;

private void FormMain_Load(object sender, EventArgs e)
{
otherForm = new FormOther();
otherForm.Show();
}

private void btnSend_Click(object sender, EventArgs e)
{
string userInput = textUserInput.Text.Trim();
if(string.IsNullOrEmpty(userInput))
{
return;
}
else
{
//otherForm.Messige = userInput;
otherForm.ReceiveMessige(userInput);
}
}
}
}

从窗体代码

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MainToOther
{
public partial class FormOther : Form
{
public FormOther()
{
InitializeComponent();
}

//通过共有属性,来实现信息的单项传递

public string Messige
{
set { libMessage.Text = value; }
}

//通过共有方法,来实现信息的单项传递
public void ReceiveMessige(string Message)
{
libMessage.Text = Message;
}

}
}

从窗体向主窗体传送数据

运行示例



方法一

示例代码

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace OtherToMain
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}



private void button1_Click(object sender, EventArgs e)
{
FormOther OtherForm = new FormOther();
主窗体主动的查询数据
if (OtherForm.ShowDialog() == DialogResult.OK)
label1.Text = OtherForm.UserInput;
else
label1.Text = "用户取消了输入!";

}
}
}

从窗体

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace OtherToMain
{
public partial class FormOther : Form
{
public FormOther()
{
InitializeComponent();
}

//通过公有属性传递数据

public string UserInput
{
get { return textBox1.Text; }
}

private void button1_Click(object sender, EventArgs e)
{
设置本窗体关闭的原因,以供主窗体查询
this.DialogResult = DialogResult.OK;
this.Close();

}

private void button2_Click(object sender, EventArgs e)
{
设置本窗体关闭的原因,以供主窗体查询
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
}

方法二:使用回调实现

主窗体

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace OtherToMain
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}


private void button1_Click(object sender, EventArgs e)
{
FormOther OtherForm = new FormOther(this);
OtherForm.Show();
}


//从窗体主动的汇报数据,Report方法供从窗体调用
public void Report(string Info)
{
label1.Text = Info;
}
}
}


从窗体

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace OtherToMain
{
public partial class FormOther : Form
{
//用于保存主窗体的引用
public FormMain mainForm = null;
//将外部的主窗体对象注入进来
public FormOther(FormMain main)
{
InitializeComponent();
mainForm = main;
}

//通过公有属性传递数据

public string UserInput
{
get { return textBox1.Text; }
}

private void button1_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBox1.Text.Trim()))
{
mainForm.Report("用户没有输入文本!");
}
else
{
mainForm.Report(textBox1.Text);
}
Close();
}

private void button2_Click(object sender, EventArgs e)
{
mainForm.Report("用户取消了输入!");
Close();
}
}
}

一个关于回调的示例

运行示例

实现代码

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CallBackExamlple
{
//公有接口
public interface ICallBack
{
void run();
}

class CallBackClass : ICallBack
{
public void run()
{
//输出当前时间
Console.WriteLine(DateTime.Now);
}
}

class CallBackClass2 : ICallBack
{
private int counter = 0;

public void run()
{
counter++;
System.Media.SystemSounds.Asterisk.Play();
Console.WriteLine("I am invoked " + counter.ToString() + " times");
}
}

class Controller
{
//定义一个对象集合
private List<ICallBack> CallBackObjects = new List<ICallBack>(); //回调对象


public void AddCallBack(ICallBack callBack)
{
CallBackObjects.Add(callBack);
}

public void Begin()
{
Console.WriteLine("敲任意键回调方法,按ESC键退出...");

while (Console.ReadKey(true).Key != ConsoleKey.Escape)
{
Console.WriteLine();
foreach(ICallBack obj in CallBackObjects)
{
obj.run();
}
}
}
}

class Program
{
static void Main(string[] args)
{
//创建控制器对象,将提供给它的回调对象传入
Controller controller = new Controller();
controller.AddCallBack(new CallBackClass());
controller.AddCallBack(new CallBackClass2());
//如需扩充程序,则只需要做如下操作
//controller.AddCallBack(new MyCallBackCla())
//启动控制器对象运行
controller.Begin();
}
}
}

综合示例

运行示例

主窗体代码

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TwoWayCommunicationInForms
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}

private FormOther OtherForm;

private void FormMain_Load(object sender, EventArgs e)
{
OtherForm = new FormOther(this);
OtherForm.Show();
}

//将numericUpDown1中数据传送到从窗口中
public void Swap()
{
OtherForm.Trabsnit = (int)numericUpDown1.Value;
}

//接收FromOther中传回的数据
public void Repter(int Info)
{
numericUpDown1.Value = Info;
}

//当numericUpDown1中数字发生改变时执行Swap
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
Swap();
}
}
}

从窗体

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TwoWayCommunicationInForms
{
public partial class FormOther : Form
{
//引用主窗体
public FormMain mainForm = null;


// //将外部的主窗体对象注入进来
public FormOther(FormMain main)
{
InitializeComponent();
mainForm = main;
}

//利用公有属性来传递数据
public int Trabsnit
{
set
{
progressBar1.Value = value;
}
get
{
return progressBar1.Value;
}
}

private void button1_Click(object sender, EventArgs e)
{
if(progressBar1.Value == 100)
{
progressBar1.Value = 0;
Trabsnit = progressBar1.Value ;
mainForm.Repter(Trabsnit);
}
else
{
progressBar1.Value++;
Trabsnit = progressBar1.Value;
mainForm.Repter(Trabsnit);
}
}

private void button2_Click(object sender, EventArgs e)
{
if(progressBar1.Value == 0)
{
progressBar1.Value = 0;
Trabsnit = progressBar1.Value;
mainForm.Repter(Trabsnit);
}
else
{
progressBar1.Value--;
Trabsnit = progressBar1.Value;
mainForm.Repter(Trabsnit);
}
}
}
}

对象广播,多个对象间信息传递

使用对象集合实现消息广播

运行示例

主窗体代码

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace UseObjectCollection
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}

//窗体对象集合
private List<FormOther> OtherForms = new List<FormOther>();

private void NewForm()
{
//每新建一个窗体,就将其加入到OtherForms对象集合中
FormOther frm = new FormOther();
OtherForms.Add(frm);
frm.Show();
}

private int counter = 0;


private void button1_Click(object sender, EventArgs e)
{
NewForm();
}

private void button2_Click(object sender, EventArgs e)
{
counter++;

//遍历对象集合,逐个回调其ShowCounter方法,计数器值成为其信参数
foreach(FormOther frm in OtherForms)
{
frm.ShowCounter(counter);
}
}
}
}

从窗体代码

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace UseObjectCollection
{
public partial class FormOther : Form
{
public FormOther()
{
InitializeComponent();
}

//供主窗体回调,显示主窗体传入的计数器值
public void ShowCounter(int counter)
{
label1.Text = counter.ToString();
}
}
}

利用委托实现消息广播

一个委托变量可以包容一个方法引用列表,能包容多种方法。
调用一次委托变量,所有方法顺序执行

主窗体代码

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace UseDelegate
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}

//将用于引用多个窗体对象所挂接的回调方法
private Action<int> ReceiverMethods;


private void NewForm()
{
//每新建一个窗体,就将其加入到OtherForms对象集合中
FormOther frm = new FormOther();
//从窗体将自己的ShowCounter方法连接到主窗体的委托变量上
ReceiverMethods += frm.ShowCounter;
frm.Show();
}

private void button1_Click(object sender, EventArgs e)
{
NewForm();
}

private int counter = 0;

private void button2_Click(object sender, EventArgs e)
{
counter++;
if(ReceiverMethods != null)
{
//调用委托调用链中的所有方法,传入当前计数值
ReceiverMethods(counter);
}
}
}
}

从窗体代码相同如上

利用事件实现消息广播

主窗体代码

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace UseEvent
{
public delegate void MyClickDelegate(int count);

public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}

//定义一个MyClick事件
public event MyClickDelegate MyClick;

private void NewForm()
{
FormOther frm = new FormOther();
//从窗体对象将ShouldCounter方法连接到MyClick事件上,响应这个事件
MyClick += frm.ShowCounter;
frm.Show();
}

private void button1_Click(object sender, EventArgs e)
{
NewForm();
}


private int counter = 0;

private void button2_Click(object sender, EventArgs e)
{
counter++;
if(MyClick != null)
{
MyClick(counter);
}
}
}
}

从窗体代码相同如上

一个对象监控多个对象

运行示例

利用对象引用回调

基本思想是从窗体定义一个MainForm字段,它引用主窗体对象
当从窗体点击按钮时,它通过对象引用调用主窗体的方法向其主动汇报情况

主窗体代码

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ButtonCounterForMoreForm
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}

//从窗体点击计数器
private int counter = 0;

//显示结果
public void ShowCounter()
{
counter++;
label2.Text = counter.ToString();
}

private void button1_Click(object sender, EventArgs e)
{
FormOther fm = new FormOther(this);
fm.Show();
}
}
}

从窗体

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ButtonCounterForMoreForm
{
public partial class FormOther : Form
{
private FormMain MainForm = null;

//对象注入
public FormOther(FormMain main)
{
InitializeComponent();
MainForm = main;
}

private void button1_Click(object sender, EventArgs e)
{
//调用主窗体公有方法,显示按钮计数
//此处无需发送任何信息,因为我们只需要统计显示点击次数
//如果确实有消息要传送给主窗体,可以在主窗体定义一个有参数的公有方法或属性
//在此处信息以实参的方式串从给主窗体
if(MainForm != null)
{
MainForm.ShowCounter();
}
}
}
}

利用委托回调

从窗体定义有一个委托类型的字段CallBackMethod
主窗体对象在创先从窗体对象时,把它自己的公有方法ShowCounter连接到此字段上
当从窗体点击按钮时,它通过委托回调主窗体的方法

主窗体代码将按钮部分改为如下代码

#
1
2
3
4
5
6
7
private void button1_Click(object sender, EventArgs e)
{
FormOther fm = new FormOther();
//将主窗体的方法挂接到从窗体上
fm.CallBackMethod = this.ShowCounter;
fm.Show();
}

从窗体代码

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ButtonCounterForMoreForm2
{
public partial class FormOther : Form
{
public FormOther()
{
InitializeComponent();
}
//用于回调主窗体挂接方法
public Action CallBackMethod = null;

private void button1_Click(object sender, EventArgs e)
{
if (CallBackMethod != null)
{
//回调主窗体方法,显示按钮计数
CallBackMethod();
}
}
}
}

利用自定义事件

从窗体定义了一个MyClick事件
主窗体的RespondTo方法响应这个事件,在事件响应代码中累加计数并更新显示

主窗体

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ButtonCounterForMoreForm2
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}

private int counter = 0;

private void ResoponseTo()
{
counter++;
label1.Text = counter.ToString();
}

private void button1_Click(object sender, EventArgs e)
{
FormOther fm = new FormOther();
//挂接从窗体事件响应函数
fm.MyClick += this.ResoponseTo;
fm.Show();
}
}
}

从窗体

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ButtonCounterForMoreForm2
{
//定义事件委托
public delegate void MyClickDelegate();

public partial class FormOther : Form
{
public FormOther()
{
InitializeComponent();
}

//自定义一个事件
public event MyClickDelegate MyClick;


private void button1_Click(object sender, EventArgs e)
{
if (MyClick != null)
{
//激发MyClick事件
MyClick();
}
}
}
}

多对多的信息交换

改多对多为一对多
设置一个专门的数据交换中心来交换数据


这部分代码写得比较乱,就不放了。

+ +
-------------本文结束感谢您的阅读-------------

本文标题:c#笔记:对象间数据传递

文章作者:史上最帅社会主义接班人

发布时间:2018年06月18日 - 21:06

最后更新:2018年06月20日 - 23:06

原始链接:https://www.buguagaoshu.com/2018/06/18/c-笔记:对象间数据传递/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

打赏链接还是要有的,万一真的有人打赏呢