2

我有两个表格。一个与所有主要代码正在执行的地方。使用此方法单击菜单项时会显示另一种形式:

Form2 videoSettings = new Form2();       

private void videoToolStripMenuItem_Click(object sender, EventArgs e)
{
    videoSettings.Show();
}

然后打开的表单包含用户可以为应用程序设置一些设置的字段。 在此处输入图像描述 然后,当单击“保存”按钮时,我想要这个变量:public int deviceIndex; 从原始表单中获取。

所以我想知道我是否可以在 Form1 中添加任何事件或东西来检测在 videoSettings (Form2) 中单击保存按钮的时间?

4

5 回答 5

6

我会以不同的方式来做。我会将 UI 处理和业务逻辑层之间的代码分开。所以你的场景将以这样的方式运行:

  1. 第一种形式发出一个事件,通知具有特定语义的按钮已被激活。处理所需的数据包含在事件数据中。
  2. 业务逻辑侦听此事件,并决定在第二个表单上发出命令。它在表单的类上调用适当的方法,将所需的信息作为参数传递(如果需要,可能会预处理参数)。
  3. 第二种形式接收来自业务逻辑的命令并更新视图。

这样问题就完全不会出现了。


示例:(我不是 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 中正确地做到这一点)。

于 2012-07-01T17:07:25.947 回答
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();
于 2012-07-01T17:21:50.677 回答
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 保存按钮时收到通知

Form2 videoSettings = new Form2();
videoSettings.SettingsSaved += new SettingsSavedEventHandler(SavedHandler);
videoSettings.Show();     
....

private void SavedHandler(object sender, SettingsSavedEventArgs ss)
{
    int deviceIndex = ss.DeviceIndex;
}

观察者模式

于 2012-07-01T17:41:24.083 回答
0

也许您可以尝试让您的第二种形式来实现INotifyPropertyChanged接口。然后,当您单击保存时,您会引发PropertyChanged事件,并在第一个表单中捕获它。

于 2012-07-01T17:10:23.123 回答
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;
于 2012-07-01T17:16:02.443 回答