我有一个 WinForms 应用程序设置来使用模型 View 演示器。为了避免 View 了解模型,我正在考虑让演示者使用 View 的实例来访问 View 文本框,并将它们数据绑定(bind)到演示者也具有的模型的实例。采用这种方法有什么问题?
我考虑过的另一个选择是让 View 拥有模型的实例。模型属性将具有 INotifyPropertyChanged 设置。在这种情况下,我可以让 View 将数据绑定(bind)设置到它具有的文本框和它也具有的模型实例。这样做有什么问题吗?
我考虑过的另一个选项是将模型属性复制到演示器中并使用 INotifyPropertyChanged 进行设置。然后,当 View 具有演示器的实例时,我可以让 View 将其文本框数据绑定(bind)到演示器中的匹配属性。通过此设置,当演示者进行数据访问调用时,它将为其本身的属性设置值,这将自动更新与演示者属性数据绑定(bind)的 View 文本框。
如果我不使用数据绑定(bind),我只需在 View 中添加 getter 和 setter,以便演示者访问 View 文本框值。演示者将使用 View getter 和 setter 来执行数据访问调用。在从数据访问调用接收数据后,演示者还将使用 setter 来设置 View 文本框值。
我正在考虑的这些选项基于我看过的文章,但也许还有另一种方法可以在我没有见过的 WinForms MVP 实现中管理数据。请提供反馈,说明推荐的方法用于管理从 View 到演示者或模型的来回数据,或者可能需要在此处添加另一层(例如某种服务)? 提前致谢。
==================================== 更新 04/10/2018
我能够设置我的应用程序,以便 View 和模型没有对演示者的引用,同时允许演示者引用 View 和模型。当我发现如何从 Presenter 中绑定(bind)到 View 控件所需的数据时,这成为可能。这不需要让 Presenter 直接访问属于 View 的可视控件。
DepartmentPresenter 字段:
public class DepartmentPresenter : IDepartmentPresenter
{
private IDepartmentView departmentView;
private IDepartmentModel departmentModel;
private IDepartmentRepository departmentRepository;
....
}
这是演示者的实例化:
void OnDisplayDepartmenSelectedRaised(object sender, DisplayDepartmentSelectedEventArgs e)
{
//Get current selected data row from Presenters BindingSource which used by the View to bind
//to its DataGridView. The view only knew it wasw a BindingSource and never had to know it
//was a collectino of DepartmentModel Data Transfer Objects (DTOs)
selectedDepartmentModel = (DepartmentModel)departmentModelBindingSource.Current;
DepartmentPresenter aDepartmentPresenter = new DepartmentPresenter(departmentView,
departmentRepository,
selectedDepartmentModel.DepartmentId);
}
演示者构造函数:
public DepartmentPresenter(IDepartmentView departmentView,
IDepartmentRepository departmentRepository,
int selectedDepartmentId)
{
this.departmentRepository = departmentRepository;
departmentModel = departmentRepository.GetById(selectedDepartmentId);
this.departmentView = departmentView;
//Subscribe to View's save request from save button so Presenter can perform work to be done on a save
this.departmentView.SaveDepartmentRaised += new EventHandler(OnSaveDepartmentRaised);
//Create bindings for data the View will use on its textBoxes
Binding departmentNameBinding = new Binding("Text", DepartmentModel, "DepartmentName", true, DataSourceUpdateMode.OnPropertyChanged);
Binding cityLocationBinding = new Binding("Text", departmentModel, "CityLocation", true, DataSourceUpdateMode.OnPropertyChanged);
Binding stateLocationBinding = new Binding("Text", departmentModel, "StateLocation", true, DataSourceUpdateMode.OnPropertyChanged);
//Store bindings into a dictionary for the View to access for its textBoxes
Dictionary<string, Binding> bindingDictionary = new Dictionary<string, Binding>();
bindingDictionary.Add("DepartmentName", departmentNameBinding);
bindingDictionary.Add("CityLocation", cityLocationBinding);
bindingDictionary.Add("StateLocation", stateLocationBinding);
//Use passed in reference to View to tell view to bind its textBoxes using the passed in Dictionary of bindings
this.departmentView.BindDisplayData(bindingDictionary);
this.departmentView.ShowView();
}
以下是 View 如何绑定(bind)到其文本框控件以响应演示者告诉它这样做的方式:
public void BindDisplayData(Dictionary<string, Binding> bindingDictinary)
{
textBoxName.DataBindings.Add(bindingDictinary["DepartmentName"]);
textBoxCity.DataBindings.Add(bindingDictinary["CityLocation"]);
textBoxState.DataBindings.Add(bindingDictinary["StateLocation"]);
}
这是 View 的接口(interface)定义:
public interface IDepartmentView
{
event EventHandler SaveDepartmentRaised;
void ShowView();
void BindDisplayData(Dictionary<string, Binding> bindingDictinary);
}
希望这能帮助那些尝试从模型 View 演示器项目中的演示器绑定(bind)到 View 的人,同时尝试避免使 View 具有演示器的实例。
最佳答案
创建一个接口(interface),您的 View 将实现该接口(interface)并可以引用演示者:
public interface IView<T> where T : class
{
T Presenter { get; set; }
}
以及 View :
public class TheView : Form, IView<ThePresenter>
{
public ThePresenter Presenter { get; set; }
}
现在您可以注入(inject)演示者,并且 View 可以使用“Presenter”属性来创建绑定(bind)。
关于c# - WinForms MVP 是否有另一种方法可以将数据绑定(bind)到 View 而无需 Presenter 访问 View 控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49595161/