我有一个绑定到ViewModel的视图
DataContext="{Binding MyViewModel, Source={StaticResource Locator}}">
文本框,…都绑定到ViewModel中的属性:
<TextBox Text="{Binding MyValue, Mode=TwoWay}"/>
<TextBlock Text="{Binding DisplayValue}"/>
ViewModel中的属性:
public MyViewModel()
{
DisplayValue = "0€";
MyValue = "0";
}
private string _myvalue;
public string MyValue
{
get
{
return _myvalue;
}
set
{
_myvalue = value;
ChangeValue();
RaisePropertyChanged(() => MyValue);
}
}
private string _displayvalue;
public string DisplayValue
{
get
{
return _displayvalue;
}
set
{
_displayvalue = value;
RaisePropertyChanged(() => DisplayValue);
}
}
private void ChangeValue()
{
//do something here and change the values of the property, e.g.:
DisplayValue = MyValue + "€";
}
这只是一个剪辑。我通常在VIEWMODEL中有~50个属性,所有的方法也在VIEWMODEL中(意味着RelayCommands和方法,这将在~50%的属性的setter中调用)。正如您所看到的,我没有使用任何模型。这是使用MVVM的正常方式,还是我应该创建一个新类并将所有属性/方法放在新类(模型)中?但是,当视图DataContext绑定到ViewModel时,我应该如何将视图中的元素与模型中的属性绑定?
编辑:让它更清楚。我有一个TextBox和TextBox被绑定到ViewModel的属性。这是使用MVVM的正确方法吗?我应该使用一个模型类只有当我有一个列表(例如组合框)或也当我有几个文本框(这将是在我的眼睛有点愚蠢和不必要)?
我希望我能理解你的意图。我的解决方案包括我在MVVM模式中使用的DependencyProperty,而不是INotifyPropertyChanged。
假设你有一个模型,它包含一个属性:
public class SymbolStatsModel
{
public string Symbol
{
get
{
return this._symbol;
}
set
{
this._symbol = value;
}
}
}
那么相应的ViewModel将是这样的。声明一个属性和一个依赖属性:
public string Symbol
{
get
{
return (string)GetValue(SymbolProperty);
}
set
{
SetValue(SymbolProperty, value);
}
}
public static readonly DependencyProperty SymbolProperty =
DependencyProperty.Register
(
"Symbol",
typeof(string),
typeof(SymbolStatsViewModel),
new FrameworkPropertyMetadata
(
string.Empty
)
);
并在ViewModel中创建一个Model类(SymStatsModel)的属性:
public SymbolStatsModel SymbolStatsModel
{
get
{
return new SymbolStatsModel(Symbol);
}
set
{
this.Symbol = value.Symbol;
}
}
这样,你分配给ViewModel Symbol Property的值将会被分配给Model Property。此外,您可以通过访问ViewModel中呈现的模型的属性,从视图中直接访问模型的属性。
这可能有点难以理解,但这确实是使视图与模型通信的方法。另一种想法是,您可以像我在解决方案中提到的那样指定模型的属性,同时使用INotifyPropertyChanged。我想是有点不成熟,但是你给了我考虑一下。
"分而治之"应该可以帮助您提高可维护性
- 试着在你的UI,逻辑组,重复部分中找到边界。
- 把它们提出来 你总是可以重置DataContext,或者使用更复杂的Binding Path,比如
MyVm.SubVm.Property