如何在 C# 中使用 MVC 模式处理事件
How to handle events with MVC Pattern in C#
我正在使用 MVC 架构模式在 C# 中实现一个小程序。该程序的目标是通过必须处理按钮单击事件的控制器单击按钮(在视图中)来更新鼠标单击计数器(在模型中)的值。
到目前为止我写的代码是有效的(它编译没有错误),但是如果无法处理按钮单击事件,因为我无法弄清楚我必须将哪种代码放入视图以及放入什么控制器。我尝试并发现可行的唯一解决方案是为视图提供对其控制器的引用。这样,事件处理程序在视图中注册和实现,并调用控制器的方法(例如Controller.DoSomethingOnButtonClick())。但是这个解决方案打破了 MVC 模式,因为据我所知,View 不应该知道它的 Controller。
模型(实现观察者模式,即"observable"):
class Model : Subject
{
private int counter = 0;
public void IncreaseCounterByOne()
{
counter++;
Notify(); // notify the observers
}
public int GetCounter()
{
return counter;
}
}
View(实现了观察者模式,就是"observer"):
class View : IObserver
{
private Model Model;
private Form MyForm = new Form();
private Label MyLabel = new Label();
private Button MyButton = new Button();
public View(Model model)
{
this.Model = model;
this.Model.Attach(this);
}
public void CreateView()
{
// create and display the view (MyForm, MyLabel, MyButton)
}
public void Update(Subject subject)
{
UpdateLabel();
}
private void UpdateLabel()
{
MyLabel.Text = "Click Counter: " + Model.GetCounter();
}
}
控制者:
class Controller
{
private Model Model;
private View View;
public Controller(Model model, View view)
{
this.Model = model;
this.View = view;
this.View.CreateView();
}
private void UpdateCounter()
{
this.Model.IncreaseCounterByOne();
}
}
我想要实现的是控制器捕获由 MyButton 生成的按钮单击事件并在其事件处理程序中处理它,我假设它是这样的:
public void OnButtonClicked(object sender, EventArgs e)
{
UpdateCounter();
}
如何在不使用对控制器的引用的情况下完成此操作?可能吗?
PS。我已经阅读了很多类似的问题,但没有找到我正在寻找的解决方案。
您 运行 遇到了一个问题,其中像 MVC 这样的模式的微不足道的例子失败了:UI 通常同时扮演 V 和 C 的角色 - 它显示数据并提供一种方法操纵它。如果您的示例涉及更多(例如,网络服务是控制器),那么关注点将更容易分开
从逻辑上讲,分离仍然存在,但是当您实际上试图将它合并到同一个 UI - 但你不应该担心这个
接受您的 UI 包含您的视图并且还包含您的控制器,因此 UI class(es) 的工作是统一所有的东西。考虑到您的标签实际上是视图,而不是您的 class 恰好称为视图。您需要获得的概念欣赏是您可以通过控制器使用 3 种不同的方式来更改模型(计时器、按钮、您向其发送一些数据的 tcp 套接字)和 3 种不同的可视化方式(标签显示一个数字,一个进度条,一个网页调用 returns 一串 'A' 与当前计数器一样长)并且你已经分离了你的关注点 - label/progbar/website 是独立的timer/button/website 并且它们彼此不了解,它们不交互,您不需要将一个引用传递给另一个以使一切正常运行。您可以移除按钮和插座,计时器将继续导致模型操作 label/progbar 将继续显示
我正在使用 MVC 架构模式在 C# 中实现一个小程序。该程序的目标是通过必须处理按钮单击事件的控制器单击按钮(在视图中)来更新鼠标单击计数器(在模型中)的值。
到目前为止我写的代码是有效的(它编译没有错误),但是如果无法处理按钮单击事件,因为我无法弄清楚我必须将哪种代码放入视图以及放入什么控制器。我尝试并发现可行的唯一解决方案是为视图提供对其控制器的引用。这样,事件处理程序在视图中注册和实现,并调用控制器的方法(例如Controller.DoSomethingOnButtonClick())。但是这个解决方案打破了 MVC 模式,因为据我所知,View 不应该知道它的 Controller。
模型(实现观察者模式,即"observable"):
class Model : Subject
{
private int counter = 0;
public void IncreaseCounterByOne()
{
counter++;
Notify(); // notify the observers
}
public int GetCounter()
{
return counter;
}
}
View(实现了观察者模式,就是"observer"):
class View : IObserver
{
private Model Model;
private Form MyForm = new Form();
private Label MyLabel = new Label();
private Button MyButton = new Button();
public View(Model model)
{
this.Model = model;
this.Model.Attach(this);
}
public void CreateView()
{
// create and display the view (MyForm, MyLabel, MyButton)
}
public void Update(Subject subject)
{
UpdateLabel();
}
private void UpdateLabel()
{
MyLabel.Text = "Click Counter: " + Model.GetCounter();
}
}
控制者:
class Controller
{
private Model Model;
private View View;
public Controller(Model model, View view)
{
this.Model = model;
this.View = view;
this.View.CreateView();
}
private void UpdateCounter()
{
this.Model.IncreaseCounterByOne();
}
}
我想要实现的是控制器捕获由 MyButton 生成的按钮单击事件并在其事件处理程序中处理它,我假设它是这样的:
public void OnButtonClicked(object sender, EventArgs e)
{
UpdateCounter();
}
如何在不使用对控制器的引用的情况下完成此操作?可能吗?
PS。我已经阅读了很多类似的问题,但没有找到我正在寻找的解决方案。
您 运行 遇到了一个问题,其中像 MVC 这样的模式的微不足道的例子失败了:UI 通常同时扮演 V 和 C 的角色 - 它显示数据并提供一种方法操纵它。如果您的示例涉及更多(例如,网络服务是控制器),那么关注点将更容易分开
从逻辑上讲,分离仍然存在,但是当您实际上试图将它合并到同一个 UI - 但你不应该担心这个
接受您的 UI 包含您的视图并且还包含您的控制器,因此 UI class(es) 的工作是统一所有的东西。考虑到您的标签实际上是视图,而不是您的 class 恰好称为视图。您需要获得的概念欣赏是您可以通过控制器使用 3 种不同的方式来更改模型(计时器、按钮、您向其发送一些数据的 tcp 套接字)和 3 种不同的可视化方式(标签显示一个数字,一个进度条,一个网页调用 returns 一串 'A' 与当前计数器一样长)并且你已经分离了你的关注点 - label/progbar/website 是独立的timer/button/website 并且它们彼此不了解,它们不交互,您不需要将一个引用传递给另一个以使一切正常运行。您可以移除按钮和插座,计时器将继续导致模型操作 label/progbar 将继续显示