我有两张表格。一个用于执行所有主要代码的地方。使用此方法单击菜单项时会显示另一种形式:
Form2 videoSettings = new Form2();
private void videoToolStripMenuItem_Click(object sender, EventArgs e)
{
videoSettings.Show();
}
然后打开的表单包含用户可以为应用程序设置一些设置的字段。
然后点击“保存”按钮我想要这个变量:public int deviceIndex;
从原始表格中取出。
所以我想知道我是否可以在Form1中添加任何事件或什么东西来检测在videoSettings(Form2)中点击保存按钮的时间?
答案 0 :(得分:6)
我会以不同的方式做到这一点。我将UI处理和业务逻辑层之间的代码分开。所以你的场景会以这样的方式运行:
这样就不会出现问题了。
示例:(我不是winforms专家,请注意最佳winforms实践的POV可能完全错误。)
第1部分(第一种形式):
class ProcessingActivatedEventArgs : EventArgs
{
public ProcessingActivatedEventArgs(int data) { MoreData = data; }
public int MoreData { get; protected set; }
}
class Form1 : Form
{
private int currentData;
public event EventHandler<ProcessingActivatedEventArgs> ProcessingActivated;
void OnButtonClick(object sender, EventArgs args)
{
// ...
if (ProcessingActivated != null)
ProcessingActivated(new ProcessingActivatedEventArgs(currentData));
}
}
第2部分:(业务逻辑)
class Controller
{
Form1 f1;
Form2 f2;
void StartFirstForm()
{
f1 = new Form1();
f1.ProcessingActivated += OnProcessingActivated;
f1.Show();
}
void OnProcessingActivated(object sender, ProcessingActivatedEventArgs args)
{
int data = args.MoreData;
f1.DisableProcessingRequests();
model.ProcessingFinished += OnProcessingFinished;
model.StartProcessing(data);
if (data > 0)
f2.DisplayDataProcessing(0, data);
else if (data < 0)
f2.DisplayDataProcessing(data, 0);
else
throw new SomeCoolException("impossible data");
}
}
第3部分:(第二种形式)
class Form2 : Form
{
public void DisplayDataProcessing(int lower, int upper)
{
// ... update the UI
}
}
请注意,此实现与Controller
相关联,并且形式比可以完成的更紧密。在WPF中,通过使用适当的DataContext
来实现解耦(但我不知道如何在WinForms中正确地执行它)。
答案 1 :(得分:1)
有很多建议,但我想补充两分钱。
你可以使用form2.ShowDialog();这将停止执行form1线程,直到form2关闭。这意味着您可以从form1:
执行此操作Form2 videoSettings = new Form2();
//show options
videoSettings.ShowDialog();
//at this point, the user has either clicked save, cancel, or closed the form
//(because the form is closed, obviously :) )
int device = videoSettings.deviceIndex;
如果你不能像这样锁定你的表单,这是使用Form2中的事件的另一种方式:
Form2 : Form
{
public event EventHandler Saved;
OnSaveButtonClicked(...)
{
if(Saved != null) Saved(this, new EventArgs());
}
}
然后从Form1:
Form2 frm = new Form2();
frm.Saved += (s, e) =>
{
//saved button clicked, retrieve value.
//also could be handled as a method, or really any way.
};
frm.Show();
答案 2 :(得分:1)
让我建议另一种方式,即最简单的ShowDialog()和业务逻辑与接口之间分离的详细方式。
我希望在Form2中创建一个新事件。我将此事件称为SettingsSaved
在Form2中添加为全局声明
public delegate void SettingsSavedEventHandler(object sender, SettingsSavedEventArgs e);
public event SettingsSavedEventHandler SettingsSaved;
并在cmdSave_Click事件中
if(SettingsSaved != null)
{
SettingsSavedEventArgs ss = new SettingsSavedEventArgs() { DeviceIndex = deviceIndex};
SettingsSaved(this, ss);
}
类SettingsSavedEventArgs的骨架
public class SettingsSavedEventArgs: EventArgs
{
public int DeviceIndex {get; set;}
// Other settings could be added here
}
现在在调用Form2的代码中,我们可以订阅该事件,并在用户单击Form2 Save按钮时收到通知
Form2 videoSettings = new Form2();
videoSettings.SettingsSaved += new SettingsSavedEventHandler(SavedHandler);
videoSettings.Show();
....
private void SavedHandler(object sender, SettingsSavedEventArgs ss)
{
int deviceIndex = ss.DeviceIndex;
}
答案 3 :(得分:0)
也许您可以尝试使用第二种形式来实现INotifyPropertyChanged界面。然后,当您单击“保存”时,您可以提高 PropertyChanged 事件,并以第一种形式捕获它。
答案 4 :(得分:0)
您可以传递类似这样的信息
private Form1 mainForm = null;
public Form2(Form callingForm)
{
mainForm = callingForm as Form1;
InitializeComponent();
}
然后,您可以像这样访问Form2中的Form1属性:
//Call this in Save button click event
this.mainForm.deviceIndex;