IDataErrorInfo 索引器和数组属性
本文关键字:数组 属性 索引 IDataErrorInfo | 更新日期: 2023-09-27 18:32:52
我有一个自定义类,它实现了 IDataErrorInfo 接口,并且有几个属性绑定到 UI 中的文本框。string this[string name]
索引器适用于常规的 int/string 属性,但我似乎无法让它与 string[] 属性一起使用。例如绑定
<TextBox Text="{Binding StringEntry, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="30" />
有效,但绑定
<TextBox Text="{Binding StringList[0], UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="30" />
不会。int[] 属性也是如此。它甚至根本不触发索引器函数调用。有没有办法让它与数组属性一起使用,还是会强制我为每个数组元素定义一个属性?
编辑:完整的类,因为看起来我不清楚。
class MyObject : INotifyPropertyChanged, IDataErrorInfo
{
public MyObject()
{
stringEntry = "text";
stringList = new string[] { "text1", "text2" };
}
private string[] stringList;
public string[] StringList
{
get
{
return this.stringList;
}
set
{
if (this.stringList != value)
{
this.stringList = value;
this.NotifyPropertyChanged("StringList");
}
}
}
private string stringEntry
public string StringEntry
{
get
{
return this.stringEntry;
}
set
{
if (this.stringEntry != value)
{
this.stringEntry = value;
this.NotifyPropertyChanged("StringEntry");
}
}
}
public override string Error
{
get
{
return null;
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public override string this[string name]
{
get
{
string result = null; // I have a breakpoint here, it's never triggered
// when I change the text in the StringList
// It DOES work for the StringEntry though.
switch (name)
{
case "StringEntry":
if (string.IsNullOrEmpty(StringEntry))
{
result = "Entry cannot be emtpy";
}
break;
case "StringList[0]": // doesn't work like this
if (string.IsNullOrEmpty(StringList[0]))
{
result = "Entry cannot be emtpy";
}
break;
case "StringList": // nor like this
if (string.IsNullOrEmpty(StringList[0]))
{
result = "Entry cannot be emtpy";
}
break;
}
return result;
}
}
}
使用绑定Text="{Binding StringList[0],
,它将始终引用 StringList
属性的第一个索引字符串,并且不会调用索引器。
如果要引用索引器,请尝试使用Text="{Binding [StringList[0]],
在这种情况下StringList[0]
它将被视为索引器的键,而不是属性本身。
编辑: 更新
class MyObject : INotifyPropertyChanged, IDataErrorInfo
{
public MyObject()
{
stringEntry = "text";
stringList = new string[] { "text1", "text2" };
}
private string[] stringList;
public string[] StringList
{
get
{
return this.stringList;
}
set
{
if (this.stringList != value)
{
this.stringList = value;
this.NotifyPropertyChanged("StringList");
}
}
}
private string stringEntry;
public string StringEntry
{
get
{
return this.stringEntry;
}
set
{
if (this.stringEntry != value)
{
this.stringEntry = value;
this.NotifyPropertyChanged("StringEntry");
}
}
}
public string Error
{
get
{
return null;
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public string this[string name]
{
get
{
string result = null; // I have a breakpoint here, it's never triggered
// when I change the text in the StringList
// It DOES work for the StringEntry though.
switch (name)
{
case "StringEntry":
if (string.IsNullOrEmpty(StringEntry))
{
result = "Entry cannot be emtpy";
}
break;
case "[(0)]": // works like this, this block is updated
if (string.IsNullOrEmpty(StringList[0]))
{
result = "Entry cannot be emtpy";
}
if (string.IsNullOrEmpty(StringList[1]))
{
result = "Entry cannot be emtpy";
}
break;
case "StringList": // not required
if (string.IsNullOrEmpty(StringList[0]))
{
result = "Entry cannot be emtpy";
}
break;
}
return result;
}
}
public string this[int index]
{
get { return StringList[index]; }
set
{
StringList[index] = value;
}
}
}
<TextBox Grid.Column="1" Text="{Binding Path=[(sys:Int32)0], UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="5"/>
在这里,我们为数组StringList
实现了包装器,它将在索引值更改时发出通知,这将触发验证索引器代码。