我正在研究自定义验证器绑定。我在 UWP 项目中使用多个验证器类。这些验证器是没有任何接口的自定义实现,我想绑定验证器的
IsValid
属性。我的目标是避免在虚拟机中创建只读代理属性以使用绑定功能,我想使用字典仅存储和读取一个属性的验证器。
这是我的验证器类:
public class Validator : ModelValidator<Model>
{
...
}
基类包含需要绑定的
IsValid
属性。
public class ModelValidator<Model> : INotifyPropertyChanged
{
...
private bool _isValid;
public bool IsValid
{
get { return _isValid; }
set { SetField(ref _isValid, value); }
}
}
目前我必须为每个验证器创建只读属性。
public class VM : INotifyPropertyChanged
{
...
public Validator Validator
{
get { return Validators['Validator']; } // I can add key check to avoid exception.
}
}
并使用创建的代理属性进行绑定。
<TextBlock Visibility={Binding Validator.IsValid} />
为了避免创建代理属性,我发现此解决方案有效,但我无法触发 PropertyChanged 事件来刷新绑定。
<TextBlock Visibility={x:Bind ((local:VM)DataContext).Validators['Validator'].IsValid} />
如果我使用内置字典,当验证器不存在时它会抛出异常。因此,只有当我在绑定执行之前创建验证器并将其放入字典中(在 VM 构造函数中)时,它才有效。
第二个版本有点混乱,但我必须避免字典的默认索引器逻辑,以避免有关项目不在字典中的异常。它允许稍后在虚拟机逻辑中添加验证器(初始化等)。
public class MyDictionary : Dictionary<string, IValidator>
{
public new IValidator this[string key]
{
get { return Get(key); }
...
}
public IValidator Get(string key)
{
IValidator o;
if (TryGetValue(key, out o))
{
return o;
}
return null;
}
}
此版本还选择了正确的验证器,并且可以稍后创建验证器,但我不需要整个验证器来进行绑定,而只需要它的
IsValid
属性。
<TextBlock Visibility={{Binding Validators, Converter={StaticResource ValidatorSelectionConverter}, ConverterParameter=Validator}} />
是否可以在字典中使用验证器并使绑定起作用?我应该在代码中更改/添加什么才能获得完整的解决方案?
问题是我必须显式添加 Mode="TwoWay" 绑定选项才能正常工作。
<TextBlock Visibility={x:Bind ((local:VM)DataContext).Validators['Validator'].IsValid, Mode="TwoWay"} />