我是WPF和绑定的新手,我想看看是否有办法在数组元素和控件之间进行双向绑定:
我的ViewModel有一个如下属性:
public ObservableCollection<MeaseurementValue> MeasurementValues
{
get
{
return Config.MeasurementValues;
}
set
{
if (value == null) return;
Config.MeasurementValues = value;
OnPropertyChanged("MeasurementValues");
QpatConfig.SerializeConfigFile(Config,
Path.GetPathRoot(Environment.GetFolderPath(Environment.SpecialFolder.System)) + "//Qualcomm//QPAT//qpat.config");
}
}
其中MeasurementValues的定义如下:
public class MeaseurementValue
{
public string TestName { get; set; }
public int value { get;set; }
}
Xaml看起来如下:
<TextBox HorizontalAlignment="Left" Grid.Column="1" Grid.Row="1" Height="23" Margin="14,20,0,0" TextWrapping="Wrap" Text="{Binding MeasurementValues[0].value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="124" />
因此xaml中的元素绑定到ViewModel中的Arrayelement。但是当我在文本控件中更改该属性时,它不会调用ViewModel的setter。
我还改变了我的代码,即数组中的evey元素也是必须通知的,所以看起来如下:
public class MeaseurementValue : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string TestName { get; set; }
private int _value;
public int value
{
get { return _value; }
set { _value = value; OnPropertyChanged("value"); }
}
void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
但那也行不通
我们与Arrays有什么不同,与原始类型相反?
答案 0 :(得分:2)
setter被调用,而不是你期望的那个。在双向绑定中,只更新路径中的最后一个属性(在目标 - >源方向上)。
想想这样 - 如果你用C#编写它,你会发生什么?
MeasurementValues[0].value = 1;
这里发生的是首先调用MeasurementValues
getter ,然后调用数组索引器的 getter ,但 setter 属于value
属性。所以没有理由让数组的setter被调用。你是远离MeasurementValues
setter的两个属性访问者。即使你写了
MeasurementValues[0] = new MeasurementValue();
不会调用MeasurementValues
setter。仅
MeasurementValues = new ObservableCollection<MeaseurementValue>();
会导致你所指的setter被调用。这与绑定完全相同。属性路径中的 last 项是双向绑定中使用的唯一setter。在您的情况下,它是value
属性。
如果要在每次设置value
属性时保存配置,您可以:
ValueChanged
中创建MeaseurementValue
事件,并在创建每个项目时将其挂钩