Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用C语言在两个windows窗体之间进行通信#_C#_Winforms_Properties - Fatal编程技术网

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
}