C# 当选中form2上的复选框时,如何更改Form1 label.text?

C# 当选中form2上的复选框时,如何更改Form1 label.text?,c#,winforms,events,C#,Winforms,Events,我是c语言的新手,正在尝试我的第一个实验,用两种不同的形式 我想让你在表格1上有一个标签1和一个按钮1,在表格2上有一个复选框1 Form1上的按钮1打开Form2,选中Form2上的复选框1后,label1中的文本将发生更改 我认为这必须使用事件来完成,但到目前为止,事件是唯一真正让我困惑的事情,所以我想本质上这个问题更多的是关于事件的使用。如果我在MSDN和其他网站上查找它,我也会感到非常困惑 非常感谢您的帮助,这让我感到非常愚蠢。在此场景中,您可以使用CheckedChanged事件: 注

我是c语言的新手,正在尝试我的第一个实验,用两种不同的形式

我想让你在表格1上有一个标签1和一个按钮1,在表格2上有一个复选框1

Form1上的按钮1打开Form2,选中Form2上的复选框1后,label1中的文本将发生更改

我认为这必须使用事件来完成,但到目前为止,事件是唯一真正让我困惑的事情,所以我想本质上这个问题更多的是关于事件的使用。如果我在MSDN和其他网站上查找它,我也会感到非常困惑


非常感谢您的帮助,这让我感到非常愚蠢。

在此场景中,您可以使用CheckedChanged事件:

注意,您必须更改Form1中的访问修饰符,并将Label1公开,以便Form2可以更改Text属性

为此,转到Form1,选择Label1 goto Properties,选择Modifiers并从Private更改为Public。然后,Form2将可以访问标签。

Form1:

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

    private void button1_Click(object sender, EventArgs e)
    {
        var form = new Form2();
        form.Changed += (o, args) => label1.Text = "some";

        form.ShowDialog();
    }
}
表格2:

public partial class Form2 : Form
{
    public delegate void ChangedEventHandler(object sender, EventArgs e);

    public event ChangedEventHandler Changed;

    public Form2()
    {
        InitializeComponent();
    }

    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {
        if (Changed != null)
        {
            Changed(this, e);
        }
    }
}
使用CheckedChanged事件的复选框


此外,您还可以查看如何使用C中的事件。

您可以直接从Form1实例订阅Form2实例中复选框的event CheckedChanged。 在Form1内部,就在显示Form2之前,订阅复选框的CheckedChanged事件

Form2 frm = new Form2();
frm.chkBox1.CheckedChanged += new EventHandler(this.ReceiveCheckedChanged);
frm2.ShowDialog();
然后在Form1中为Form2中引发的checkedChanged事件定义此处理程序

private void ReceiveCheckedChanged(object sender, EventArgs e)
{
   CheckBox chk = sender as CheckBox;
   if(chk.Checked)
       this.label1.Text = "Checked";
   else
       this.label1.Text = "UnChecked";
}
为此,您需要将复选框上的属性修饰符从Private更改为Public

这样,您的Form2就不需要知道存在Form1,并且每次有人单击复选框时,您都需要更改另一个表单中的标签。更改其内部状态的责任标签上的文本位于表单1上,该表单已通知系统其要求。

使用控制器和事件来解耦表单

这样做的正确方法是通过引入控制器类,并使用事件来表示状态更改,从而将这两种形式彼此解耦

这里有一个例子

首先,创建一个名为WindowsFormsApplication1的新默认Windows窗体应用程序,并添加两个窗体,form1和form2

然后在form1中添加一个名为button1的按钮和一个名为label1的标签

然后在表单2中添加一个名为checkbox1的复选框

在form1设计器中,双击该按钮为其添加单击处理程序

在form2设计器中,双击复选框为其添加更改处理程序

现在添加一个名为Controller的新类,并向其添加以下代码:

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    internal sealed class Controller
    {
        public void RunForm1()
        {
            _form1 = new Form1();
            // The next line defines our response to the button being pressed in Form1
            _form1.ButtonClicked += (sender, args) => showForm2();
            Application.Run(_form1);
        }

        private void showForm2()
        {
            var form2 = new Form2();
            // The next line defines our response to the checkbox changing in Form2.
            form2.CheckBoxChanged += 
                (sender, args) => 
                _form1.SetLabel("Checkbox = " + ((CheckBox)sender).Checked);

            form2.ShowDialog(_form1);
        }

        private Form1 _form1 ;
    }
}
现在将Form1.cs更改为:

并将Form2.cs更改为:

最后,将Program.cs更改为:

现在运行程序并单击按钮,然后单击复选框几次。您将看到Form1中的标签正在更改


通过这种方式,您将Form1与Form2完全解耦,并将控制逻辑放在一个单独的控制器类中。

它们是继Linq和Lambdas之后C中更复杂的部分之一。你看过这个MSDN页面了吗?不过,活动绝对是做到这一点的方法。是的,你可以轻松做到这一点。你尝试过什么?自从我注册stackoverflow以来的五个月里,这似乎是C标签所有形式中最流行的问题,我甚至回答了其中的几个。非常感谢!如果我理解正确的话。。eventhandler在这种情况下调用定制的ReceiveCheckedChanged,因此每次调用CheckedChanged时都会运行它,因为复选框处于选中/未选中状态?我真的不明白为什么frm.chkBox1.CheckedChanged+=neweventhandlerthis.ReceiveCheckedChanged;必须在showdialog之前,因为showdialog是模态的。当您输入该代码时,在关闭Form2实例之前不会退出。因此无法从复选框订阅和接收事件。您从何处获得变量Form1?
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    internal sealed class Controller
    {
        public void RunForm1()
        {
            _form1 = new Form1();
            // The next line defines our response to the button being pressed in Form1
            _form1.ButtonClicked += (sender, args) => showForm2();
            Application.Run(_form1);
        }

        private void showForm2()
        {
            var form2 = new Form2();
            // The next line defines our response to the checkbox changing in Form2.
            form2.CheckBoxChanged += 
                (sender, args) => 
                _form1.SetLabel("Checkbox = " + ((CheckBox)sender).Checked);

            form2.ShowDialog(_form1);
        }

        private Form1 _form1 ;
    }
}
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1: Form
    {
        // Here's where we announce our event handler to the world:
        public event EventHandler ButtonClicked;

        public Form1()
        {
            InitializeComponent();
        }

        public void SetLabel(string text)
        {
            label1.Text = text;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // We make a copy of ButtonClicked before checking it for null because
            // in a multithreaded environment some other thread could change it to null
            // just after we checked it for nullness but before we call it, which would
            // cause a null reference exception.
            // A copy cannot be changed by another thread, so that's safe to use:

            var handler = ButtonClicked;

            if (handler != null)
                handler(sender, e);
        }
    }
}
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form2: Form
    {
        // Here's the event handler for the check box:
        public event EventHandler CheckBoxChanged;

        public Form2()
        {
            InitializeComponent();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            var handler = CheckBoxChanged;

            if (handler != null)
                handler(sender, e);
        }
    }
}
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Controller controller = new Controller();
            controller.RunForm1();
        }
    }
}