从Form2更新Form1对象

时间:2018-07-03 17:00:45

标签: c# inheritance

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

Form1:

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

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

Form2:

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

什么都没发生。我可以将数据从form1获取到form2,但是我不能发送,我可以,但是什么也没发生……为什么?谢谢

4 个答案:

答案 0 :(得分:1)

使用Form f1 = new Form();可以创建新表单,而不是访问已经打开的表单,并且您不会调用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(); 
}

答案 1 :(得分:1)

这里提到的其他解决方案适用于您的特定情况,但我鼓励您放眼全局,并设计一个适用于大多数情况的通用解决方案。

您的问题从本质上可以归结为 根据另一种形式的事件在一种形式上做某事

我认为最好的方法是

  • Form1自己执行所有操作。
  • Form2自己执行所有操作。
  • 如果您需要根据Form1上发生的事件在Form2上做某事,请让Form2通知Form1那里发生了某件事,因此请自己做东西。
  • 如有必要,将数据从Form2传递到Form1

因此,我将为此使用delegates

想象一下,您的Button上有一个Label和一个Form1。单击该按钮将打开Form2,在该按钮上您还有另一个Button。在Form2上单击此按钮应更改Form1上标签的背景颜色。因此,我们的设置将如下所示。您没有提到它是Winforms还是WPF,因此为了方便起见,我使用WPF,但是两者的想法都是相同的。

Form1

enter image description here

Form2

enter image description here

在我的Form1中,我要声明一个具有以下签名的公共代表:

public delegate void NotifyEvent();

也就是说,此委托表示一种不带任何参数且返回类型为void的方法。这个想法是让Form2Form1中“调用”一个方法,该方法实质上是 notify 通知在Form2上单击了按钮。因此,如果有一种方法可以从Form1调用位于Form2中的方法,那么我们可以将Form1上发生的事件通知Form2到目前为止?

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

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

要实现此目的,我将在NotifyEvent中定义一个类型为Form1的委托,如下所示,然后向其中注册ButtonClickedOnForm2()方法。您后面的Form1代码应如下所示:

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();
    }
}

因此,现在我们需要修改Form2。我们需要告诉我们在单击按钮时要调用哪个委托。为此,我将像这样将委托传递给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();
    }
}

现在,在Form2上单击按钮时,它将调用委托。在我们的Form1上,我们已经说过,如果委托被调用,它应该继续执行ButtonClickedOnForm2方法。在这种方法中,我们编写了代码来更改标签的背景色。那应该可以解决您的问题。


传递数据

此外,如果要将数据从Form2传递到Form1,则可以简单地将参数添加到委托定义中。假设您要将stringForm2传递到Form1。然后,将您的代表更改为如下所示:

public delegate void NotifyEvent(string data);

方法ButtonClickedOnForm2如下:

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上标签的文本和背景颜色,如下所示:

enter image description here

答案 2 :(得分:0)

谢谢您的构造器构想。无论如何,这在全球范围内对我不起作用。因此,我需要将其简化为:

具有构造函数的表格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'):

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

到目前为止效果很好...

答案 3 :(得分:0)

尝试此代码

Form1:

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


public void ColorChange()
{
    label2.ForeColor = Color.Red;
}

Form2:

public Form1 f1;

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

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