【发布时间】:2013-08-16 06:53:36
【问题描述】:
我想在 WP 应用程序中使用 MVVM pattern。我对这种模式有一些想法。但我不明白一些事情。我不知道这样做是否是好习惯。
所以,我有Model。
模型是一种数据结构。字段和属性的集合。
型号
public class Person : INotifyPropertyChanged
{
private string name;
private GeoCoordinate coordinate;
public string Name
{
get
{
return name;
}
set
{
if (this.name != value)
{
this.name = value;
this.RaisePropertyChanged("Name");
}
}
}
public GeoCoordinate Coordinate
{
get
{
return this.coordinate;
}
set
{
if (this.coordinate != value)
{
this.coordinate = value;
this.RaisePropertyChanged("Coordinate");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
ViewModel 初始化模型的字段。
视图模型
public class PersonViewModel : INotifyPropertyChanged
{
public Person User
{
get;
private set;
}
public PersonViewModel()
{
this.User = new Person();
}
public LoadData()
{
Service.GetUser((result) =>
{
this.User.Name = result.Name;
this.User.Coordinate = result.Coordinate;
});
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
查看
PersonViewModel _viewModel;
this.DataContext = _viewModel;
_viewModel.LoadData();
以下是我想澄清的时刻:
- ViewModel 如何通知 View 加载数据出错,结束加载?
- 我可以将部分日期传递给 View(没有数据绑定,技术上是可能的,我的意思是,这在模式下是允许的)?
例如,在 ViewModel 中:
public LoadData(Action<Person, Exception> act)
{
Service.GetUser((result, error) =>
{
if (error != null)
{
act.Invoke(null, error);
}
else
{
this.User.Name = result.Name;
this.User.Coordinate = result.Coordinate;
act.Invoke(result, null);
}
});
}
在查看:
_viewModel.LoadData((result, error) =>
{
if (error != null)
{
//error data loading
}
else
{
//successfully loading
}
});
这太可怕了,可能这种方法破坏了整个概念。但是,例如,我使用 Jeff Wilcox 静态地图。
<jwMaps:StaticMap
Provider="Bing"
Visibility="Visible">
<jwMaps:StaticMap.MapCenter>
<geo:GeoCoordinate
Latitude ="50"
Longitude="50" />
</jwMaps:StaticMap.MapCenter>
</jwMaps:StaticMap>
我无法将坐标绑定到此控件。我试过了,不行。如果使用
StaticMap.MapCenter =
new GeoCoordinate() { Latitude = user.Latitude, Longitude = user.Longitude };
然后工作。
在委托的情况下,我可以在一个成功的分支中做到这一点......
请帮忙指点一下。
【问题讨论】:
-
你可能想从一个 MVVM 框架开始,否则你最终会编写大量的管道代码来使东西正常工作 - 如果没有太多关于该模式的经验,你可能会犯其他人所犯的错误已经解决了。我并不是说你不应该尝试去理解它,而是我说它已经被理解了,并且有很多不同的方式来实现这个模式。我最喜欢的 MVVM 框架之一是 Caliburn Micro,它适用于 WP7(可能还有 WP8,尽管我还没有查看最新版本)。
-
刚刚检查过,是的,它支持 WP8。试试 MVVM Light、Prism 和 Caliburn Micro - caliburnmicro.codeplex.com
-
对于绑定问题-听起来您所说的控件不支持绑定。这更多是控件的问题,但您可以通过使用事件聚合器(或中介者模式的实现)来解决它 - 基本上您在视图中订阅某种类型的消息并从您的 ViewModel 发送该类型的消息.您的中介位于中间并接收消息,并将它们委托给订阅者。这样,您可以替换消息链的任一端,因为它们不相互依赖
-
谢谢!我检查了 Caliburn Micro,我打开了一些示例,到目前为止,这对我来说很神奇。 :) Caliburn 命名空间中有这么多类,需要学习。我在例子中看到了Event Aggregator,想明白这个想法,我喜欢这种方法。
标签: c# windows-phone-7 data-binding mvvm windows-phone-8