对多个WPF控件应用类似的绑定
本文关键字:绑定 应用 控件 WPF | 更新日期: 2023-09-27 18:16:57
如果已经被问到,请提前道歉;我花了一段时间谷歌和搜索堆栈溢出-但找不到类似的问题。
我有一个WPF窗口,里面有很多很多的数据输入控件。所有控件都有到视图模型的双向绑定,并使用IDataErrorInfo进行验证。
这里给出了一个绑定的例子:
<TextBox >
<TextBox.Text>
<Binding Path="Street" Mode="TwoWay" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
<Binding.ValidationRules>
<ExceptionValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
这个绑定和其他所有绑定的唯一区别是路径。
我所有的绑定都需要验证规则,以及关于何时更新的指令,因为有很多跨域验证正在进行。
我的问题是-我可以应用相同的绑定到一个文本框没有所有的复制/粘贴,我目前必须做上述的例子?
我在想,也许我应该滚动我自己的绑定子类来照顾它-但我不知道这是不是一个好的做法?
更新:我刚刚尝试了一个绑定的子类,像这样:
public class ExceptionValidationBinding : Binding
{
public ExceptionValidationBinding()
{
Mode = BindingMode.TwoWay;
NotifyOnValidationError = true;
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
ValidatesOnDataErrors = true;
ValidationRules.Add(new ExceptionValidationRule());
}
}
使我的xaml看起来像这样:
<TextBox Text="{bindings:ExceptionValidationBinding Path=PostCode}" />
它似乎有效…就像我说的,不知道这种方法是否有问题。
如果您不希望视图的代码隐藏中有任何代码,您可以创建一个MarkupExtension
并在XAML中使用它。下面是MarkupExtension
的一个例子:
public class MyBinding : MarkupExtension
{
public string ThePath { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
Binding binding = new Binding(ThePath) {
Mode = BindingMode.TwoWay,
NotifyOnValidationError = true,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
ValidatesOnDataErrors = true
};
binding.ValidationRules.Add(new ExceptionValidationRule());
return binding;
}
}
然后你可以在XAML:
中这样做<TextBox Text="{local:MyBinding ThePath=Street}">
Edit:看起来这给出了一个运行时错误。将行return binding;
改为return binding.ProvideValue(serviceProvider);
。我想从Binding
派生类实际上是更好的,但我将留在这里无论如何:)
即使您正在使用MVVM,您也可以从代码后面应用绑定(因为它仍然是纯视图逻辑)。据我所知,从XAML内部"模板化"绑定是不可能的。
在你的代码后面做,像这样:
void InitBinding() {
Address bindingSource = ...
String[] paths = new String[] { "Street", "City", etc... };
foreach(TextBox textBox in ...) {
String path = ... // get the path for this textbox
Binding binding = new Binding( path );
binding.Source = bindingSource;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding( textBox, TextBox.TextProperty, binding );
}
}
为了后代——我想要的答案是我自己的第一次更新。这是因为子类化绑定似乎没有副作用,这让我可以直接使用XAML覆盖我在绑定上设置的任何默认值,这是我使用标记扩展思想无法做到的(没有大量的工作)。
感谢大家花时间帮我解决这个问题。
我的答案
我刚刚尝试了一个绑定的子类,像这样:
public class ExceptionValidationBinding : Binding
{
public ExceptionValidationBinding()
{
Mode = BindingMode.TwoWay;
NotifyOnValidationError = true;
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
ValidatesOnDataErrors = true;
ValidationRules.Add(new ExceptionValidationRule());
}
}
使我的xaml看起来像这样:
<TextBox Text="{bindings:ExceptionValidationBinding Path=PostCode}" />
它似乎有效…