我对MVVM很新,所以请耐心等待。我有一个视图模型类,其公共属性实现如下:
public List<float> Length
{
get;
set;
}
在我的视图的XAML中,我有几个文本框,每个文本框都绑定到此长度列表中的特定元素:
<TextBox Text="{Binding Length[0], Converter=DimensionConverter}" />
<TextBox Text="{Binding Length[2], Converter=DimensionConverter}" />
<TextBox Text="{Binding Length[4], Converter=DimensionConverter}" />
DimensionConverter是一个IValueConverter派生类,它将值格式化为维度(即屏幕上的文本框中480.0英寸变为40'0“),然后再返回(即字符串需要35'0”,产生420.0)英寸为源)
我的问题:我需要能够验证List中的每个值,因为它在关联的TextBox中已更改。对于某些人,我可能需要根据输入的值修改List中的其他值(即更改Length [0]处的float将更改Length [4]处的值并更新屏幕)。
有没有办法重新处理属性以允许索引器?或者,我是否需要为列表中的每个项目创建单独的属性(这真的使List不必要)?基本上,因为我已经拥有了float的集合,所以我希望能够编写MVVM代码来验证每个项目的修改。
思考? (并且,提前感谢)
答案 0 :(得分:1)
您可以使用ObservableCollection<float>
代替List<float>
,并处理CollectionChanged
事件以检测用户何时更改值。
答案 1 :(得分:1)
不会是这样的:
<ItemsControl ItemsSource="{Binding Length}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Mode=TwoWay, Converter=DimensionConverter}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
接近你想要的东西?
它将显示整个列表,并允许用户修改值,只要您的IValueConverter实现ConvertBack,它们将直接返回到列表。
然后像Thomas所说的那样验证或实施ObservableLinkedList
你现在所做的事情看起来很脏,而且只有几行代码......
答案 2 :(得分:1)
如果你有一个实现INotifyPropertyChanged的类来提供列表长度不变的属性,那就太好了。
答案 3 :(得分:1)
如果要使用mvvm验证文本输入,请创建一个可以在viewmodel中使用的模型
public class FloatClass : INotifyPropertyChanged
{
private ICollection parentList;
public FloatClass(float initValue, ICollection pList) {
parentList = pList;
this.Value = initValue;
}
private float value;
public float Value {
get { return this.value; }
set {
if (!Equals(value, this.Value)) {
this.value = value;
this.RaiseOnPropertyChanged("Value");
}
}
}
private void RaiseOnPropertyChanged(string propName) {
var eh = this.PropertyChanged;
if (eh != null) {
eh(this, new PropertyChangedEventArgs(propName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
在您的viewmodel中,您可以使用此类型号
public class FloatClassViewmModel : INotifyPropertyChanged
{
public FloatClassViewmModel() {
this.FloatClassCollection = new ObservableCollection<FloatClass>();
foreach (var floatValue in new[]{0f,1f,2f,3f}) {
this.FloatClassCollection.Add(new FloatClass(floatValue, this.FloatClassCollection));
}
}
private ObservableCollection<FloatClass> floatClassCollection;
public ObservableCollection<FloatClass> FloatClassCollection {
get { return this.floatClassCollection; }
set {
if (!Equals(value, this.FloatClassCollection)) {
this.floatClassCollection = value;
this.RaiseOnPropertyChanged("FloatClassCollection");
}
}
}
private void RaiseOnPropertyChanged(string propName) {
var eh = this.PropertyChanged;
if (eh != null) {
eh(this, new PropertyChangedEventArgs(propName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
这是xaml示例
<ItemsControl ItemsSource="{Binding Path=FloatClassViewmModel.FloatClassCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Value, Mode=TwoWay, Converter=DimensionConverter}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
希望这会有所帮助