我正在撰写关于代码设计的论文,我正在比较MV-C,P和VM,看看哪一个最适合WPF。在我的研究中,我意识到MVVM是其他标准中数据绑定的明显选择。
即使我知道这一点,我必须在某种意义上“证明”这一点,所以我在MVP和MVVM中创建一个完全相同的应用程序,但处理代码的方式不同。有了这个,我将解释这些代码模式的优缺点,但在我使用MVP应用程序创建时遇到了问题。
我有一个带有“商务逻辑”的模型,我的演示者创建了我的视图可以显示的这些模型对象的列表。
我的问题是我如何展示它们
在MVVM中,我将列表绑定到ListBox
原因,这就是MVVM“做”的原因。
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
我知道您应该将MVVM用于WPF,但为了证明为什么它更好我需要展示MVP如何在WPF中工作。
答案 0 :(得分:3)
当你使用WPF时,就像你所说的那样,通过数据绑定来使用MVVM。 MVP通常与Windows形式一起使用,其中没有数据绑定可用。如果您希望您的应用程序具有相同的功能并使用相同的技术(WPF),则无法避免使用绑定,或者至少更难以执行。只要您通过演示者与模型交谈,您仍然在使用MVP。您可以自行决定是否要使用
如果你正在使用绑定我会说(不确定)你使用的是 SuperVising Presenter ,这不是“推荐”,但是不建议在WPF中使用MVP ......
编辑示例
例如,如果要显示列表,则需要具有包含要显示的对象的列表属性的接口。
public interface myinterface
{
ObservableCollection<YourModel> ListName {get; set;}
}
然后在您的演示者中将数据“推送”到该列表
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一起工作(以一种小方式)
答案 1 :(得分:1)
我无法在评论中添加尽可能多的代码,因此我会发布一个答案。如果有什么不清楚,请给我一个反馈,以便我给你更多细节。
从您已展示的示例中我将开始并将 View 绑定到 Presenter ,这应该是 View 和模型,你可以在这里看到:
(来自wikipedia article的图片)
查看应该向演示者发送事件/更改,演示者应该是&#34;大脑/逻辑&#34; View 决定是否应该更新 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 的另一种方式可能如下:
假设您有类似的查看,只需创建一个演示者:
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 ,或者每个窗口需要一个控件,这将取决于您。