我想通过事件从另一个视图更新一个视图。目前我不知道该怎么做?
我的案例:我有一个计算引擎,当我执行计算时,我想通知用户执行的步骤。所以我打开一个带有RichTextBox
控件的新窗口来显示所需的信息。当执行一个新步骤时,我想引发一个事件以便在另一个窗口 ( RichTextBox
) 中显示文本。
有没有可以帮助我做到这一点的例子?
我想通过事件从另一个视图更新一个视图。目前我不知道该怎么做?
我的案例:我有一个计算引擎,当我执行计算时,我想通知用户执行的步骤。所以我打开一个带有RichTextBox
控件的新窗口来显示所需的信息。当执行一个新步骤时,我想引发一个事件以便在另一个窗口 ( RichTextBox
) 中显示文本。
有没有可以帮助我做到这一点的例子?
基本上,最好不要直接更改视图,而是对模型或“ViewModel”进行操作。所以这是我的建议:
为计算定义一个 ViewModel:
public class CalculationViewModel
{
public event Action ResultChanged;
private string _result = string.Empty;
public string Result
{
get { return _result; }
set { _result = value; Notify(); }
}
private void Notify()
{
if (ResultChanged!= null)
{
ResultChanged();
}
}
}
您的视图(您提到的显示结果的表单)订阅了该视图。它将具有可用于设置模型的属性。
private CalculationViewModel _model;
public CalculationViewModel Model
{
get { return _model; };
set
{
if (_model != null) _model.ResultChanged -= Refresh;
_model = value;
_model.ResultChanged += Refresh;
};
}
public void Refresh()
{
// display the result
}
您将有一段代码将这些东西粘在一起(如果您愿意,可以将其称为控制器):
var calculationModel = new CalculationViewModel();
var theForm = new MyForm(); // this is the form you mentioned which displays the result.
theForm.Model = calculationModel;
var engine = new CalculationEngine();
engine.Model = calculationModel;
此代码创建模型、引擎和视图。模型被注入到视图和引擎中。到那时,视图订阅模型的任何更改。现在,当引擎运行时,它会将结果保存到其模型中。该模型将通知其订阅者。视图将收到通知并调用它自己的 Refresh() 方法来更新文本框。
这是一个简化的例子。以此为起点。特别是,WinForms 提供了自己的数据绑定机制,您可以利用它,因此您可以使用其 DataSource 属性将文本框绑定到模型,而不是创建一段名为“刷新”的代码。这要求您也使用 WinForm 自己的更改通知机制。但我认为你需要先了解这个概念,然后再继续让这在幕后完成。
只是在没有编译检查的情况下添加它,当心拼写错误。
public partial class Form1: Form {
protected void btnCalculation_Click(object sender, EventArgs e) {
var form2 = new Form2();
form2.RegisterEvent(this);
form2.Show();
OnCalculationEventArgs("Start");
// calculation step 1...
// TODO
OnCalculationEventArgs("Step 1 done");
// calculation step 2...
// TODO
OnCalculationEventArgs("Step 2 done");
}
public event EventHandler<CalculationEventArgs> CalculationStep;
private void OnCalculationStep(string text) {
var calculationStep = CalculationStep;
if (calculationStep != null)
calculationStep(this, new CalculationEventArgs(text));
}
}
public class CalculationEventArgs: EventArgs {
public string Text {get; set;}
public CalculationEventArgs(string text) {
Text = text;
}
}
public partial class Form2: Form {
public void RegisterEvent(Form1 form) {
form1.CalculationStep += form1_CalculationStep;
}
private void form1_CalculationStep(object sender, CalculationEventArgs e) {
// Handle event.
// Suppose there is a richTextBox1 control;
richTextBox1.Text += e.Text;
}
}