我尝试从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,但是我不能发送,我可以,但是什么也没发生……为什么?谢谢
答案 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
中,我要声明一个具有以下签名的公共代表:
public delegate void NotifyEvent();
也就是说,此委托表示一种不带任何参数且返回类型为void的方法。这个想法是让Form2
在Form1
中“调用”一个方法,该方法实质上是 notify 通知在Form2
上单击了按钮。因此,如果有一种方法可以从Form1
调用位于Form2
中的方法,那么我们可以将Form1
上发生的事件通知Form2
到目前为止?
现在,如果我在Form1
中编写这样的方法,并从Form2
中调用它,那应该可以实现我们的目标。在这里,lblDisp
是Label
中的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
,则可以简单地将参数添加到委托定义中。假设您要将string
从Form2
传递到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
上标签的文本和背景颜色,如下所示:
答案 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();
}