我应该通过绑定使用 MVP 和 WPF 显示数据吗?
Should I display data using MVP and WPF through binding?
我正在写一篇关于代码设计的论文,我正在比较 MV-C、P 和 VM,看看哪一个最适合 WPF。在我的研究过程中,我意识到 MVVM 是其他标准中数据绑定的明显选择原因。
即使我知道这一点,在某种意义上我也必须"prove",所以我在 MVP 和 MVVM 中创建了一个应用程序,它做的事情完全相同,但处理代码的方式不同。有了这个,我将解释这些代码模式的优缺点,但在我使用 MVP 应用程序创建时遇到了问题。
我有一个带有 "buisness-logic" 的模型,我的演示者创建了我的视图可以显示的这些模型对象的列表。
我的问题是如何显示它们
在 MVVM 中,我将我的列表绑定到 ListBox
因为这就是 MVVM "made" 的工作方式。
EG
<Window.Resources>
<DataTemplate DataType="{x:type model:Mymodel}">
//Some DataTemplate Definition
</DataTemplate>
</Window.Resources>
然后绑定到我的Listbox
<ListBox ItemSources={Binding someProperty} />
它没有完全编码,但你得到了手势
但如果我理解正确的话,绑定 与 MVP 不应该是这样的。
你不应该在 MVP 中绑定任何东西,因为这不是它应该如何工作的,或者我在这里错了吗?
因此,如果我不应该绑定数据,我该如何在 ListBox
中显示我的模型对象列表,这样它就不会说
Model Object
Model Object
Model Object
Model Object
我知道您应该为 WPF 使用 MVVM,但为了证明为什么它更好,我需要展示 MVP 如何在 WPF 中工作。
我无法在评论中添加尽可能多的代码,所以我会 post 一个答案。如果有什么不清楚的地方,请给我反馈,我会为您提供更多详细信息。
根据您展示的示例,我将着手进行从 View 到 Presenter 的绑定,这应该是[之间的桥梁] =34=]View 和 Model 如您所见:
(图片来自wikipedia article)
View 应该发送 events/changes 给演示者,演示者应该是 View 的 "brain/logic"决定是否应该更新 Model。
假设您的 View 像这样:
<UserControl x:Class="EntryNamespace.MeView"
... >
<!-- ListItems should return collection of Presenters -->
<ListView ItemsSource="{Binding ListItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ListView.ItemTemplate>
<DataTemplate>
<!-- Elementcontent should be a property inside Presenter that returns value from Model -->
<Button Content="{Binding ElementContent}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</UserControl>
您可以像这样创建一个 Presenter :
class Presenter : INotifyPropertyChanged
{
public ObservableCollection<ListItemPresenter> ListItems
{
get { return GetItems(); }
set { SetItems(value); }
}
ObservableCollection<ListItemPresenter> GetItems()
{
// private logic to retrieve `ListItemPresenter` collection from model
var collection = new ObservableCollection<ListItemPresenter>();
foreach(ListItem listItem in Model.Items)
collection.Add(listItem.GetPresenter());
return collection;
}
void SetItems(ObservableCollection<ListItemPresenter> objects)
{
// private logic to transfer `ListItemPresenter` collection to model
// remember to call NotifyPropertyChanged("ListItems");
Model.Items.Clear();
foreach(ListItemPresenter presenter in objects)
Model.Items.Add(presenter.GetModel());
NotifyPropertyChanged("ListItems");
}
}
你的模特可以看起来像这样:
public class ListItem
{
ListItemPresenter m_Presenter;
public ListItemPresenter GetPresenter()
{
return m_Presenter;
}
string m_ElementContent;
public string ElementContent
{
get { return m_ElementContent; }
set { m_ElementContent = value; }
}
public ListItem(ListItemPresenter presenter)
{
m_Presenter = presenter;
}
}
使用 Presenter 的另一种方法可能如下所示:
假设您有类似的 View 只需创建一个 Presenter:
public class Presenter
{
ObservableCollection<ListItem> m_ListItems = new ObservableCollection<ListItem>();
public ObservableCollection<List> ListItems
{
get { return m_ListItems; }
}
public Presenter(MeView view)
{
Binding binding = new Binding("ListItems");
binding.Source = ListItems;
view.MeListView.SetBinding(ListView.ItemsSourceProperty, binding);
// other view events, bindings etc.
}
}
这不是 View 和 Model 之间间接通信的最佳方式,但应该给你一些小提示。如果您想拆分控件,让每个控件都有自己的 Presenter,或者您想要每个 window.
一个,则由您决定
当您使用 WPF 时,正如您所说,它是通过数据绑定与 MVVM 一起工作的。 MVP 通常与 Windows-form 一起使用,其中没有可用的数据绑定。如果您希望您的应用程序具有相同的功能并使用相同的技术 (WPF),则无法避免使用绑定,或者至少更难做到。只要您通过演示者与您的模型交谈,您仍在使用 MVP。你可以自己决定是否要使用
- 被动视图 - 演示者处理视图和模型之间的所有对话
- SuperVising Presenter - View 了解模型,而 Presenter 处理 "difficult-code" 在视图和模型之间需要处理的事情太多了。
如果您正在使用绑定,我会说(不确定)您正在使用 SuperVising Presenter 而不是 "recommended",但是在 WPF 中使用 MVP 是也不推荐所以...
编辑示例
例如,如果你想显示一个列表,你需要一个界面,该界面有一个 属性 包含你要显示的对象的列表。
public interface myinterface
{
ObservableCollection<YourModel> ListName {get; set;}
}
然后在您的演示者中 "push" 该列表的数据
private myinterface _my;
public Presenter(myinterface my)
{ this._my = my;}
_my.ListName = // Add whatever Data you want into this list.
在你看来
<ListBox ItemSource ={Binding ListName}>
<ListBox.ItemTemplate>Set how you want to display the list</ListBox.ItemTemplate>
这是一个不清楚的示例,但希望可以让您了解 MVP 如何与 WPF 一起工作(以一种小的方式)
我正在写一篇关于代码设计的论文,我正在比较 MV-C、P 和 VM,看看哪一个最适合 WPF。在我的研究过程中,我意识到 MVVM 是其他标准中数据绑定的明显选择原因。
即使我知道这一点,在某种意义上我也必须"prove",所以我在 MVP 和 MVVM 中创建了一个应用程序,它做的事情完全相同,但处理代码的方式不同。有了这个,我将解释这些代码模式的优缺点,但在我使用 MVP 应用程序创建时遇到了问题。
我有一个带有 "buisness-logic" 的模型,我的演示者创建了我的视图可以显示的这些模型对象的列表。
我的问题是如何显示它们
在 MVVM 中,我将我的列表绑定到 ListBox
因为这就是 MVVM "made" 的工作方式。
EG
<Window.Resources>
<DataTemplate DataType="{x:type model:Mymodel}">
//Some DataTemplate Definition
</DataTemplate>
</Window.Resources>
然后绑定到我的Listbox
<ListBox ItemSources={Binding someProperty} />
它没有完全编码,但你得到了手势
但如果我理解正确的话,绑定 与 MVP 不应该是这样的。
你不应该在 MVP 中绑定任何东西,因为这不是它应该如何工作的,或者我在这里错了吗?
因此,如果我不应该绑定数据,我该如何在 ListBox
中显示我的模型对象列表,这样它就不会说
Model Object
Model Object
Model Object
Model Object
我知道您应该为 WPF 使用 MVVM,但为了证明为什么它更好,我需要展示 MVP 如何在 WPF 中工作。
我无法在评论中添加尽可能多的代码,所以我会 post 一个答案。如果有什么不清楚的地方,请给我反馈,我会为您提供更多详细信息。
根据您展示的示例,我将着手进行从 View 到 Presenter 的绑定,这应该是[之间的桥梁] =34=]View 和 Model 如您所见:
(图片来自wikipedia article)
View 应该发送 events/changes 给演示者,演示者应该是 View 的 "brain/logic"决定是否应该更新 Model。
假设您的 View 像这样:
<UserControl x:Class="EntryNamespace.MeView"
... >
<!-- ListItems should return collection of Presenters -->
<ListView ItemsSource="{Binding ListItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ListView.ItemTemplate>
<DataTemplate>
<!-- Elementcontent should be a property inside Presenter that returns value from Model -->
<Button Content="{Binding ElementContent}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</UserControl>
您可以像这样创建一个 Presenter :
class Presenter : INotifyPropertyChanged
{
public ObservableCollection<ListItemPresenter> ListItems
{
get { return GetItems(); }
set { SetItems(value); }
}
ObservableCollection<ListItemPresenter> GetItems()
{
// private logic to retrieve `ListItemPresenter` collection from model
var collection = new ObservableCollection<ListItemPresenter>();
foreach(ListItem listItem in Model.Items)
collection.Add(listItem.GetPresenter());
return collection;
}
void SetItems(ObservableCollection<ListItemPresenter> objects)
{
// private logic to transfer `ListItemPresenter` collection to model
// remember to call NotifyPropertyChanged("ListItems");
Model.Items.Clear();
foreach(ListItemPresenter presenter in objects)
Model.Items.Add(presenter.GetModel());
NotifyPropertyChanged("ListItems");
}
}
你的模特可以看起来像这样:
public class ListItem
{
ListItemPresenter m_Presenter;
public ListItemPresenter GetPresenter()
{
return m_Presenter;
}
string m_ElementContent;
public string ElementContent
{
get { return m_ElementContent; }
set { m_ElementContent = value; }
}
public ListItem(ListItemPresenter presenter)
{
m_Presenter = presenter;
}
}
使用 Presenter 的另一种方法可能如下所示:
假设您有类似的 View 只需创建一个 Presenter:
public class Presenter
{
ObservableCollection<ListItem> m_ListItems = new ObservableCollection<ListItem>();
public ObservableCollection<List> ListItems
{
get { return m_ListItems; }
}
public Presenter(MeView view)
{
Binding binding = new Binding("ListItems");
binding.Source = ListItems;
view.MeListView.SetBinding(ListView.ItemsSourceProperty, binding);
// other view events, bindings etc.
}
}
这不是 View 和 Model 之间间接通信的最佳方式,但应该给你一些小提示。如果您想拆分控件,让每个控件都有自己的 Presenter,或者您想要每个 window.
一个,则由您决定当您使用 WPF 时,正如您所说,它是通过数据绑定与 MVVM 一起工作的。 MVP 通常与 Windows-form 一起使用,其中没有可用的数据绑定。如果您希望您的应用程序具有相同的功能并使用相同的技术 (WPF),则无法避免使用绑定,或者至少更难做到。只要您通过演示者与您的模型交谈,您仍在使用 MVP。你可以自己决定是否要使用
- 被动视图 - 演示者处理视图和模型之间的所有对话
- SuperVising Presenter - View 了解模型,而 Presenter 处理 "difficult-code" 在视图和模型之间需要处理的事情太多了。
如果您正在使用绑定,我会说(不确定)您正在使用 SuperVising Presenter 而不是 "recommended",但是在 WPF 中使用 MVP 是也不推荐所以...
编辑示例
例如,如果你想显示一个列表,你需要一个界面,该界面有一个 属性 包含你要显示的对象的列表。
public interface myinterface
{
ObservableCollection<YourModel> ListName {get; set;}
}
然后在您的演示者中 "push" 该列表的数据
private myinterface _my;
public Presenter(myinterface my)
{ this._my = my;}
_my.ListName = // Add whatever Data you want into this list.
在你看来
<ListBox ItemSource ={Binding ListName}>
<ListBox.ItemTemplate>Set how you want to display the list</ListBox.ItemTemplate>
这是一个不清楚的示例,但希望可以让您了解 MVP 如何与 WPF 一起工作(以一种小的方式)