C# 从Form2更新Form1对象

C# 从Form2更新Form1对象,c#,inheritance,C#,Inheritance,我尝试从Form2更新Form1值,但什么也没发生。也没有错误,奇怪 表格1: public static Form2 f2{ get; set; } = new Form2(); private void addButton1_Click(object sender, EventArgs e) { f2.Show(); } 表格2: public void button1_Click(object sender

我尝试从Form2更新Form1值,但什么也没发生。也没有错误,奇怪

表格1:

 public static Form2 f2{ get; set; } = new Form2();

 private void addButton1_Click(object sender, EventArgs e)
        {        
            f2.Show(); 
        }
表格2:

 public void button1_Click(object sender, EventArgs e)
    {
        Form f1 = new Form();
        f1.label2.ForeColor = Color.Red;
    }
public Form1 f1;

public Form2(Form1 m)
{
    this.f1 = m;
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{ 
    f1.Show();
    f1.ColorChange();
}

什么也没发生。我可以从表格1中获取表格2的数据,但是我不能发送,我的意思是我可以,但是什么都没有发生。。。为什么?感谢
表单f1=新表单()
您正在创建一个新表单,而不是访问一个已经打开的表单,并且您不调用
f1.Show()因此它将永远不会显示。您需要一个已打开的引用。例如,将表格1作为构造函数参数传递给表格2

表格2:

public partial class Form2 : Form
{
    private readonly Form1 _form1;

    public Form2 (Form1 from1)
    {
        _form1 = form1;
        InitializeComponent();
    }

    public void button1_Click(object sender, EventArgs e)
    {
        _form1.label2.ForeColor = Color.Red;
    }
}
表格1:

// Cannot be static as we need a reference to `this`
private Form2 _f2;
public Form2 f2 {
    get {
        if (_f2 == null) {
            _f2 = new Form2(this);  // Pass form 1 as parameter to form 2.
        }
        return _f2;
    }
}

private void addButton1_Click(object sender, EventArgs e)
{        
    f2.Show(); 
}

带有
表单f1=新表单()
您正在创建一个新表单,而不是访问一个已经打开的表单,并且您不调用
f1.Show()因此它将永远不会显示。您需要一个已打开的引用。例如,将表格1作为构造函数参数传递给表格2

表格2:

public partial class Form2 : Form
{
    private readonly Form1 _form1;

    public Form2 (Form1 from1)
    {
        _form1 = form1;
        InitializeComponent();
    }

    public void button1_Click(object sender, EventArgs e)
    {
        _form1.label2.ForeColor = Color.Red;
    }
}
表格1:

// Cannot be static as we need a reference to `this`
private Form2 _f2;
public Form2 f2 {
    get {
        if (_f2 == null) {
            _f2 = new Form2(this);  // Pass form 1 as parameter to form 2.
        }
        return _f2;
    }
}

private void addButton1_Click(object sender, EventArgs e)
{        
    f2.Show(); 
}

谢谢你的建议。无论如何(这)在全球范围内对我不起作用。因此,我需要将其简化为:

表格2(含建造商):

  public Form1 _form1 { get; set; }
        public Form2(Form1 form1)
        {
            _form1 = form1;
            InitializeComponent();
        }

    public void button1_Click(object sender, EventArgs e)
        {
            _form1.label2.ForeColor = Color.Red;
        }
    }
表单1每次需要调用时使用参数创建新对象(因为“this”):


到目前为止效果很好…

谢谢你的建议。无论如何(这)在全球范围内对我不起作用。因此,我需要将其简化为:

表格2(含建造商):

  public Form1 _form1 { get; set; }
        public Form2(Form1 form1)
        {
            _form1 = form1;
            InitializeComponent();
        }

    public void button1_Click(object sender, EventArgs e)
        {
            _form1.label2.ForeColor = Color.Red;
        }
    }
表单1每次需要调用时使用参数创建新对象(因为“this”):

到目前为止工作正常…

请尝试此代码

表格1:

private void addbutton1_Click(object sender, EventArgs e)
{
    Form2 f2 = new Form2(this);
    f2.Show();
}


public void ColorChange()
{
    label2.ForeColor = Color.Red;
}
表格2:

 public void button1_Click(object sender, EventArgs e)
    {
        Form f1 = new Form();
        f1.label2.ForeColor = Color.Red;
    }
public Form1 f1;

public Form2(Form1 m)
{
    this.f1 = m;
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{ 
    f1.Show();
    f1.ColorChange();
}
试试这个代码

表格1:

private void addbutton1_Click(object sender, EventArgs e)
{
    Form2 f2 = new Form2(this);
    f2.Show();
}


public void ColorChange()
{
    label2.ForeColor = Color.Red;
}
表格2:

 public void button1_Click(object sender, EventArgs e)
    {
        Form f1 = new Form();
        f1.label2.ForeColor = Color.Red;
    }
public Form1 f1;

public Form2(Form1 m)
{
    this.f1 = m;
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{ 
    f1.Show();
    f1.ColorChange();
}

这里提到的其他解决方案适用于您的具体情况,但我鼓励您从全局出发,设计一个适用于大多数情况的通用解决方案

您的问题本质上归结为基于另一种形式的事件在一种形式上做某事。

在我看来,最好的方法是:

  • Form1
    自己执行所有操作
  • Form2
    自己执行所有操作
  • 如果您需要根据在
    Form2
    上发生的事件在
    Form1
    上执行某些操作,请让
    Form2
    通知
    Form1
    那里发生了一些事情,然后自己去做
  • 如有必要,将数据从
    Form2
    传递到
    Form1
因此,我会利用这一点

假设您的
表单1上有一个
按钮
和一个
标签
。单击该按钮将打开
表单2
,在该表单上有另一个
按钮
。单击
Form2
上的此按钮应更改
Form1
上标签的背景色。所以我们的设置是这样的。您没有提到它是
Winforms
还是
WPF
,因此为了方便起见,我使用
WPF
,但两者的想法都是一样的

表格1

表格2

在我的
表格1
中,我将声明一个具有以下签名的公共代理:

public delegate void NotifyEvent();
public delegate void NotifyEvent(string data);
也就是说,此委托表示一个不接受任何参数且具有void返回类型的方法。其思想是让
Form2
Form1
中“调用”一个方法,该方法本质上通知按钮被点击
Form2
。因此,如果我们有办法从
Form2
调用驻留在
Form1
中的方法,那么我们可以通知
Form1
到目前为止发生在
Form2
上的事件

现在,如果我在
Form1
中编写一个这样的方法,并让它从
Form2
调用,这应该可以实现我们的目标。这里,
lblDisp
Form1
中的
标签

public void ButtonClickedOnForm2()
{
    lblDisp.Background = new SolidColorBrush(Colors.LawnGreen);
}
为了实现这一点,我将在
Form1
中定义一个类型为
NotifyEvent
的委托,如下所示,并向其注册
按钮clickedonform2()
方法。您的
表单1
代码应该如下所示

public delegate void NotifyEvent();

public partial class Form1 : Window
{
    public NotifyEvent notifyDelegate;

    Form2 form2 = null;

    public Form1()
    {
        InitializeComponent();
        // This is 'registering' the ButtonClickedOnForm2 method to the delegate.
        // So, when the delegate is invoked (called), this method gets executed.
        notifyDelegate += new NotifyEvent(ButtonClickedOnForm2);
    }

    public void ButtonClickedOnForm2()
    {
        lblDisp.Background = new SolidColorBrush(Colors.LawnGreen);
    }

    private void BtnOpen_Click(object sender, RoutedEventArgs e)
    {
        // Passing the delegate to `Form2`
        form2 = new Form2(notifyDelegate);
        form2.Show();
    }
}
因此,现在我们需要修改
表单2
。我们需要告诉我们在按钮单击时调用哪个委托。为此,我将在
Form2
的构造函数中传递委托,如下所示:

public partial class Form2 : Window
{
    NotifyEvent notifyDel;

    public Form2(NotifyEvent notify)
    {
        InitializeComponent();
        notifyDel = notify;
    }

    private void BtnOK_Click(object sender, RoutedEventArgs e)
    {
        // This invokes the delegate, which in turn calls the ButtonClickedOnForm2 method in Form1.
        notifyDel.Invoke();
    }
}
public void ButtonClickedOnForm2(string data)
{
    lblDisp.Content = data;
    lblDisp.Background = new SolidColorBrush(Colors.LawnGreen);
}
现在,当在表单2上单击按钮时,它将调用委托。在我们的
表单1
中,我们告诉它,如果调用了委托,它应该继续执行
按钮ClickedonForm2
方法。在该方法中,我们编写了更改标签背景颜色的代码。这应该能解决你的问题


传递数据 此外,如果要将数据从
Form2
传递到
Form1
,只需将参数添加到代理定义中即可。假设要将
字符串
Form2
传递到
Form1
。然后,将代理更改为如下所示:

public delegate void NotifyEvent();
public delegate void NotifyEvent(string data);
方法
按钮clickedonform2
如下所示:

public partial class Form2 : Window
{
    NotifyEvent notifyDel;

    public Form2(NotifyEvent notify)
    {
        InitializeComponent();
        notifyDel = notify;
    }

    private void BtnOK_Click(object sender, RoutedEventArgs e)
    {
        // This invokes the delegate, which in turn calls the ButtonClickedOnForm2 method in Form1.
        notifyDel.Invoke();
    }
}
public void ButtonClickedOnForm2(string data)
{
    lblDisp.Content = data;
    lblDisp.Background = new SolidColorBrush(Colors.LawnGreen);
}
然后在
Form2
上,通过如下方式传递字符串来调用委托:

private void BtnOK_Click(object sender, RoutedEventArgs e)
{
    // This invokes the delegate, which in turn calls the ButtonClickedOnForm2 method in Form1.
    notifyDel.Invoke("I am from Form2");
}
现在,单击
Form2
上的按钮应更改
Form1
上标签的文本和背景色,如下所示:

public delegate void NotifyEvent();
public delegate void NotifyEvent(string data);

这里提到的其他解决方案适用于您的具体情况,但我鼓励您从全局出发,设计一个适用于大多数情况的通用解决方案

您的问题本质上归结为基于另一种形式的事件在一种形式上做某事。

在我看来,最好的方法是:

  • Form1
    自己执行所有操作
  • Form2
    自己执行所有操作
  • 如果您需要根据在
    Form2
    上发生的事件在
    Form1
    上执行某些操作,请让
    Form2
    通知
    Form1
    那里发生了一些事情,然后自己去做
  • 如有必要,将数据从
    Form2
    传递到
    Form1