我不知道正确的措辞来描述我在这里想做的事情......所以我只是展示它。
我知道这个 xaml 有效:
<TextBox>
<TextBox.Text>
<Binding Path="Location" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<domain:NotEmptyValidationRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
Run Code Online (Sandbox Code Playgroud)
但这非常冗长。我想以类似的方式来做...
<TextBox Text={Binding Path=Location, UpdateSourceTrigger=PropertyChanged,
ValidationRules={domain:NotEmptyValidationRuleMarkup ValidateOnTargetUpdated=True}}"/>
Run Code Online (Sandbox Code Playgroud)
我创建了一个名为 的类NotEmptyValidationRuleMarkup,它返回 的实例NotEmptyValidationRule,并且它可以工作。项目构建得很好,运行得很好,一切都完全按照我的预期进行。但是,我无法再在设计器中查看我的窗口。它给了我一个无效标记错误,因为The property "ValidationRules" does not have an accessible setter.. 确实如此,ValidationRules 没有 setter。如果我尝试通过 C# 代码设置 ValidationRules,则会出现编译错误。但由于某种原因,当我在 XAML 中分配它时,它实际上确实构建并运行得很好。我很困惑。有没有一种方法可以让我在不提升窗口设计视图的情况下完成这项工作?
即使 xaml 解释器碰巧将标记扩展转换为有效的东西,但这并没有得到真正的支持。
以下是无法使用 Binding 标记扩展/{Binding} 表达式形式设置的 Binding 属性。
...
ValidationRules:该属性采用 ValidationRule 对象的通用集合。这可以表示为 Binding 对象元素中的属性元素,但没有现成的属性解析技术可用于 Binding 表达式。请参阅验证规则的参考主题。
但是,让我建议一种不同的方法:不要将自定义标记扩展嵌套在绑定中,而是将绑定嵌套在自定义标记扩展中:
[ContentProperty("Binding")]
[MarkupExtensionReturnType(typeof(object))]
public class BindingEnhancementMarkup : MarkupExtension
{
public BindingEnhancementMarkup()
{
}
public BindingEnhancementMarkup(Binding binding)
{
Binding = binding;
}
[ConstructorArgument("binding")]
public Binding Binding { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
Binding.ValidationRules.Add(new NotEmptyValidationRule());
return Binding.ProvideValue(serviceProvider);
}
}
Run Code Online (Sandbox Code Playgroud)
并使用如下:
<TextBox Text="{local:BindingEnhancementMarkup {Binding Path=Location, UpdateSourceTrigger=PropertyChanged}}"/>
Run Code Online (Sandbox Code Playgroud)
当然,对于生产,您可能需要在标记扩展中添加更多检查,而不是仅仅假设一切都已就位。
| 归档时间: |
|
| 查看次数: |
1459 次 |
| 最近记录: |