我有费用屏幕,其中包含一个文本框,我可以在其中列出费用的价格。由于我为这个文本框构建了很多逻辑(验证等),我想将它提取到一个单独的控件并在其他屏幕上重用它。我试图以mvvm风格构建它。这就是我现在所拥有的:
ExpenseView
<page>
<Label Text={Binding Date} />
<wpfControls:CurrencyTextBoxView ViewModel="{Binding PriceViewModel}" />
</page>
ExpenseViewModel
public class ExpenseViewModel : INotifyPropertyChanged
{
private ExpenseModel Model { get; }
public string Date
{
get { return Model.Date.ToString(); }
set
{
Model.Date = DateTime.Parse(value);
RaisePropertyChanged();
}
}
private CurrencyTextBoxViewModel _priceViewModel;
public CurrencyTextBoxViewModel PriceViewModel
{
get { return _priceViewModel; }
set { _priceViewModel = value; }
}
}
ExpenseModel
public class ExpenseModel
{
public DateTime Date { get; set; }
public decimal Price { get; set; } // This is the bit I don't know how to implement correctly
}
CurrencyTextBoxView
<control>
<TextBox Content={Binding Price} />
</control>
CurrencyTextBoxViewModel
public class CurrencyTextBoxViewModel : INotifyPropertyChanged
{
private CurrencyModel Model { get; }
public string Price
{
get { return Model.Price.ToString(); }
set
{
Model.Price = decimal.Parse(value);
RaisePropertyChanged();
}
}
}
CurrencyModel
public class CurrencyModel
{
public decimal Price { get; set; }
}
现在的问题是:我需要在我的ExpenseModel中拥有Price属性(因为它被保存在数据库中)。我不想在我的CurrencyModel中使用Date属性(因为并非总是有意义)。
我应该将CurrencyModel保留在我的ExpenseModel中吗?当货币文本框中的文本发生变化时,如何有效地更新它? 此外,ExpenseModel位于与我的其他类不同的项目中,我不希望使用CurrencyModel使该项目依赖于该项目。
每当CurrencyTextBoxViewModel.Price字符串更改时,我应该从CurrencyTextBoxViewModel监听PropertyChanged事件并更新ExpenseModel.Price吗?我喜欢我的视图模型充当视图模型解析器的方式(Date属性示例)。有没有办法实现PriceViewModel,以便其getter直接从ExpenseModel返回数据(因此它充当解析器)?
我知道有很多方法可以实现它,但我正在寻找最符合mvvm的方法。另外,我不确定我是否正确实现了整个模式?
答案 0 :(得分:0)
对于Date
属性,如果不需要序列化,则只将其放在视图模型上。
我该怎么做:
如果您想重用CurrencyTextBox
,我不会将控件与模型联系起来。不需要CurrencyModel
。在DependencyProperty
上准备CurrencyText
(说CurrencyTextBox
)。视图如下:
<xxx:CurrencyTextBox CurrencyText="{Binding Currency}" />
您可以省略CurrencyTextBoxViewModel
,因为CurrencyText
可以绑定到内部TextBox.Text
(或者只更新视图模型上的相关属性)。无论如何,通过双向绑定,当CurrencyText
更新时,ExpenseViewModel.Currency
也会更新,您可以在这里更新模型。
我认为听模型的事件是可以的,因为视图模型比模型短。但是,如果新值与旧值相同,则应阻止传播事件触发。
该模型充当数据的起源并执行业务逻辑。视图模型只是模型的阴影,因此它通常很薄。考虑使用一些MVVM框架来理解它。