C# 用C语言在两个windows窗体之间进行通信#
我有两种表格,一种是主表格,另一种是期权表格。例如,假设用户单击主窗体上的我的菜单:C# 用C语言在两个windows窗体之间进行通信#,c#,winforms,properties,C#,Winforms,Properties,我有两种表格,一种是主表格,另一种是期权表格。例如,假设用户单击主窗体上的我的菜单:Tools->Options,这将导致显示我的选项窗体 我的问题是如何将选项表单中的数据发送回主表单?我知道我可以使用属性,但我有很多选择,这似乎是一件乏味而奇怪的事情 那么最好的方法是什么呢?属性是一个选项,共享静态类-另一个选项,事件-另一个选项…在这种情况下,最好是有一些选项服务类/接口,可以通过IServiceProvider访问 只要在某些内容发生更改时添加一个事件,应用程序的其余部分就可以响应它。您可
Tools->Options
,这将导致显示我的选项窗体
我的问题是如何将选项表单中的数据发送回主表单?我知道我可以使用属性,但我有很多选择,这似乎是一件乏味而奇怪的事情
那么最好的方法是什么呢?属性是一个选项,共享静态类-另一个选项,事件-另一个选项…在这种情况下,最好是有一些
选项服务
类/接口,可以通过IServiceProvider
访问
只要在某些内容发生更改时添加一个事件,应用程序的其余部分就可以响应它。您可以尝试。将选项保留在一个单独的类中,然后使用AutoMapper在类和窗体之间切换数据。创建一个类,并将所有属性放入该类中。。在父类中创建一个属性,并从子类(选项)表单中设置该属性
public SettingsResults GetNewSettings()
{
if(this.ShowDialog() == DialogResult.Ok)
{
return new SettingsResult { ... };
}
else
{
return null;
}
}
你可以这样称呼它:
...
using(var fb = new FormB())
{
var s = fb.GetNewSettings();
...
// Notify other parts of the application that settings have changed.
}
private void frm_Message(object sender, EventArgs e)
{
Lbl.Text = ((Form2)sender).Message;
}
1 public delegate void dlFuncToBeImplemented(string signal);
2 public static event dlFuncToBeImplemented OnFuncToBeImplemented;
3 public static void FuncToBeImplemented(string signal)
4 {
5 OnFuncToBeImplemented(signal);
6 }
private void ObserverRegister()//will contain all observer function registration
{
Observer.OnFuncToBeImplemented += Observer_OnFuncToBeImplemented;
/*and more observer function registration............*/
}
void Observer_OnFuncToBeImplemented(string signal)//the function that will occur when FuncToBeImplemented(signal) will call
{
MessageBox.Show("Signal "+signal+" received!", "Atention!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
这可能有点回避了您的问题,但是我的设置对话框使用了应用程序设置结构 我找不到一个与我的做法类似的好例子(实际上有一个实际的类+对象),但这涵盖了另一种做法:
表单是一个类,就像任何其他类一样。在表单类中添加一些公共变量,并在它们单击按钮关闭表单时设置它们(从技术上讲,它们只是隐藏它) 一个VB.NET的例子,但是你会明白的- 在选项窗体类中:
Public Option1 as String = ""
等。当他们点击“确定”按钮时进行设置
因此,在主窗体中,当他们点击“选项”按钮时,您可以创建选项窗体:
OptionsForm.ShowDialog()
退出时,您可以从表单上的公共变量获取选项设置:
option1 = OptionsForm.Option1
等等。Form1触发Form2打开。Form2具有重载构造函数,该构造函数将调用表单作为参数,并向Form2成员提供其引用。这就解决了通信问题。例如,我在Form1中将Label属性公开为public,而在Form2中对其进行了修改 通过这种方法,你可以用不同的方式进行交流 //您的表格1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(this);
frm.Show();
}
public string LabelText
{
get { return Lbl.Text; }
set { Lbl.Text = value; }
}
}
//你的表格2
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private Form1 mainForm = null;
public Form2(Form callingForm)
{
mainForm = callingForm as Form1;
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
this.mainForm.LabelText = txtMessage.Text;
}
}
(来源:)
(来源:)MVC、MVP、MVVM——对于那些承认需要教程的人来说,这有点过分了。这些理论都有专门的课程 如前所述,传递对象可能是最简单的。如果将类视为对象(在这个意义上是可互换的)是新的,那么您可能需要再花2-4周的时间来确定属性和构造函数等等 无论如何,我都不是C#master,但如果您想在两种形式(也包括类/对象本身)之间传递值之外更进一步,这些概念需要非常具体。在这里,你根本不想显得刻薄,只是听起来你正在从VB6(或任何带有globals的语言)转向更结构化的语言
最终,它会点击 在对公认答案的评论中,Neeraj Gulia写道:
这将导致Form1和Form2的紧密耦合,我想应该使用自定义事件来处理此类场景 评论完全正确。公认的答案不错;对于简单的程序,尤其是对于那些刚刚学习编程并试图让基本场景正常工作的人来说,这是一个非常有用的例子,说明了一对表单是如何进行交互的 然而,确实可以而且应该避免示例导致的耦合,并且在特定示例中,事件将以通用的、解耦的方式完成相同的事情 下面是一个示例,使用接受答案的代码作为基线: Form1.cs:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Button1Click += (sender, e) => Lbl.Text = ((Form2)sender).Message;
frm.Show();
}
}
public partial class Form2 : Form
{
public event EventHandler Button1Click;
public string Message { get { return txtMessage.Text; } }
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
EventHandler handler = Button1Click;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
上面的代码创建了一个新的Form2
实例,然后在显示它之前,向该表单的按钮1添加一个事件处理程序,然后单击事件
请注意,表达式(sender,e)=>Lbl.Text=((Form2)sender).Message
由编译器自动转换为类似于(但绝对不完全类似)以下内容的方法:
实际上有很多方法/语法来实现和订阅事件处理程序。例如,使用如上所述的匿名方法,您实际上不需要强制转换sender
参数;相反,您可以直接使用frm
局部变量:(sender,e)=>Lbl.Text=frm.Message
相反,您不需要使用匿名方法。实际上,您可以声明一个常规方法,就像我上面展示的编译器生成的方法一样,然后将该方法订阅到事件:frm.Button1Click+=frm\u Message
(当然,您已经将名称frm_Message
用于该方法,就像我上面的示例一样)
无论您如何操作,当然您需要Form2
来实际实现按钮1单击事件。这很简单
Form2.cs:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Button1Click += (sender, e) => Lbl.Text = ((Form2)sender).Message;
frm.Show();
}
}
public partial class Form2 : Form
{
public event EventHandler Button1Click;
public string Message { get { return txtMessage.Text; } }
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
EventHandler handler = Button1Click;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
除了事件之外,我还声明了一个属性Message
,该属性公开Text
控件的Text
属性(并且只有Text
属性,实际上是只读的)。这允许事件的订阅者获取值,并对其执行任何需要的操作
请注意,该事件所做的只是提醒订阅者该按钮实际上已被单击。由订阅者决定如何解释或响应该事件(例如,通过检索Message
属性的值并将其分配给somet
1 public delegate void dlFuncToBeImplemented(string signal);
2 public static event dlFuncToBeImplemented OnFuncToBeImplemented;
3 public static void FuncToBeImplemented(string signal)
4 {
5 OnFuncToBeImplemented(signal);
6 }
private void ObserverRegister()//will contain all observer function registration
{
Observer.OnFuncToBeImplemented += Observer_OnFuncToBeImplemented;
/*and more observer function registration............*/
}
void Observer_OnFuncToBeImplemented(string signal)//the function that will occur when FuncToBeImplemented(signal) will call
{
MessageBox.Show("Signal "+signal+" received!", "Atention!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
public static int signal = 0;
public void button1_Click(object sender, EventArgs e)
{
Observer.FuncToBeImplemented(signal);//will call the event in the user control
}