M46*_*463 5 c# data-binding wpf mvvm
由于ViewModel的工作是“准备”模型的属性以在View中显示,因此从ViewModel引用基础Models属性的最佳方法是什么?
我现在可以考虑两种解决方案:
建筑
class Model
{
public string p1 { get; set; }
public int p2 { get; set; }
}
class ViewModel : INotifyPropertyChanged
{
// Model-instance for this ViewModel
private Model M;
public string p1
{
get { return M.p1; }
set
{
M.p1 = value;
// assuming View controls are bound to the ViewModel's properties
RaisePropertyChanged("p1");
}
}
// let's say, I only want to check a Checkbox in the View,
// if the value of p2 exceeds 10.
// Raising the property changed notification would get handled
// in the modifying code instead of the missing setter of this property.
public bool p2
{
get
{
if (M.p2 > 10)
{ return true; }
else
{ return false; }
}
}
// Initialize the Model of the ViewModel instance in its c'tor
public ViewModel()
{ M = new Model(); }
}
Run Code Online (Sandbox Code Playgroud)
捆绑
<Textbox Text="{Binding p1}"/>
<Checkbox IsEnabled="False" IsChecked="{Binding p2, Mode=OneWay}"/>
Run Code Online (Sandbox Code Playgroud)
好处
缺点
建筑
class Model
{
public string p1 { get; set; }
public int p2 { get; set; }
}
class ViewModel : INotifyPropertyChanged
{
// Model instance for this ViewModel (private field with public property)
private Model _M;
public Model M
{
get { return _M; }
set
{
_M = value;
// Raising the changing notification for the WHOLE Model-instance.
// This should cause ALL bound View-controls to update their values,
// even if only a single property actually got changed
RaisePropertyChanged("M");
}
}
// Initialize the Model of the ViewModel instance in its ctor
public ViewModel()
{ M = new Model(); }
}
Run Code Online (Sandbox Code Playgroud)
捆绑
<Textbox Text="{Binding M.p1}"/>
<Checkbox IsEnabled="False" IsChecked="{Binding M.p2, Mode=OneWay, Converter={StaticResource InverseBooleanConverter}"/>
Run Code Online (Sandbox Code Playgroud)
好处
缺点
ViewModel的责任是将Model公开给View,不应将Model的属性公开为ViewModel中的其他属性,而是将View直接绑定到模型。
此外,在模型中包含逻辑是没有错的,实际上,与ViewModel相比,在模型中包含与模型相关的代码更有意义。
这是一个例子:
public class Movie
{
private string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
//Notify property changed stuff (if required)
//This is obviously a stupid example, but the idea
//is to contain model related logic inside the model.
//It makes more sense inside the model.
MyFavourite = value == "My Movie";
}
}
private bool _MyFavourite;
public bool MyFavourite
{
get { return _MyFavourite; }
set
{
_MyFavourite = value;
//Notify property changed stuff.
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,为了更直接地回答您的问题,您应该将模型作为属性公开在视图模型中。
public class ViewModel
{
private Movie _Model;
public Movie Model
{
get { return _Model; }
set
{
_Model = value;
//Property changed stuff (if required)
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
因此,您的视图将绑定到该Model属性,就像您已经这样做一样。
编辑
在用于强制转换为类型的示例中,您可以在Model中实现一个只读属性,如下所示:
public bool MyBool
{
get
{
return MyInt > 10; }
}
}
Run Code Online (Sandbox Code Playgroud)
现在的奇妙之处在于,INotifyPropertyChanged每当MyInt更改时,您都需要为此属性调用。因此,您的其他属性如下所示:
public int MyInt
{
get { ... }
set
{
_MyInt = value;
//Notify property changed for the read-only property too.
OnPropertyChanged();
OnPropertyChanged("MyBool");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3962 次 |
| 最近记录: |