最近另一个问题一直困扰着我,我很确定这是我缺乏WPF / MVVM技能阻止我看到明显的问题。我确信解决方案很简单,但我不确定如何实现它。
我正在使用WPF / C#开发,我正在使用MVVM设计模式。
为简单起见,我将问题归结为最基本的组件。
情景:
我有一个Model,只包含一个整数。
我有一个父ViewModel,显示这个整数。
我有两个子视图模型,在父视图模型中包含,都显示这个整数。在其中一个viewmodel上,我有一个Command,用1递增整数的值。模型中的值发生了变化,实现了INotifyPropertyChanged,从而使第二个ViewModel知道了这个变化,因此可以相应地更新。
到目前为止一切正常。
但是,我对一个新功能很感兴趣,我无法让它工作。说,我在我的第二个视图模型上想要显示整数,但我想改变数据的显示方式。但是,这应该在不更改模型中的数据的情况下完成。如果模型中的数据发生变化,转换的数据将相应地改变。
作为一个例子,假设整数是5.在第二个视图模型中,我想显示整数+ 2,意思是7。 然后,数据从第一个视图模型更改为6,这意味着第二个视图模型上的属性会自动更改为8.
这是如何实现的?
一些代码,用于说明目前系统的外观:
模特:
public DataModel()
{
data = new Data();
data.Value = 2;
}
public Data data { get; set; }
数据类:
public class Data : INotifyPropertyChanged
{
private int m_Value;
public int Value
{
get { return m_Value; }
set
{
if (m_Value != value)
{
m_Value = value;
OnPropertyChanged("Value");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
mainviewmodel
public class MainViewModel : ViewModelBase
{
readonly DataModel _dataModel;
public MainViewModel()
{
_dataModel = new DataModel();
ViewModel1 = new 1ViewModel(this);
ViewModel2 = new 2ViewModel(this);
}
public 1ViewModel ViewModel1 { get; set; }
public 2ViewModel ViewModel2 { get; set; }
public Data Data
{
get { return _dataModel.data; }
}
}
以下是ChildViewmodels将自己绑定到Data对象的方式
public class 1ViewModel : ViewModelBase
{
private MainViewModel _mainViewModel;
public 1ViewModel(MainViewModel mainViewModel)
{
_mainViewModel = mainViewModel;
}
public Data Number
{
get { return _mainViewModel.data; }
}
}
在view1上,我像这样绑定了Number属性
<TextBlock Text="{Binding Path=Number.Value}" />
同样,我希望能够在viewmodel上创建第二个属性,该属性基于但不更改原始数据显示已转换的数据,并且与正在更新的数据一起更新。 优选地,它应该是一种转换器方法,它将数据转换为新数据。
希望你能提供帮助。
答案 0 :(得分:1)
ViewModel应该准备好显示数据,但不知道它的显示方式。如果您想要更改数据在View中的显示方式,那么您将使用Converter。这将允许您为多个视图使用相同的ViewModel并具有不同的外观。
此外,将ViewModel包装在ViewModel中并不一定是您想要的方式。 ViewModel通常具有关联的View。如果您没有查看ViewModel,请将数据视为典型类,然后继续使用单个ViewModel。
答案 1 :(得分:0)
使用IValueConverter:
public class AddConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (int)value + (int)parameter;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (int)value - (int)parameter;
}
}
在您的XAML中,添加资源:
并更新你的绑定:
我在这里使用了ConverterParameter,但如果需要,您可以对值进行硬编码。可能还想在转换器中添加一些检查,因为如果类型不正确,它会抛出异常。