您可以在 xaml 的 1 行内使用 Binding ValidationRule 吗? [英] Can you use a Binding ValidationRule within 1 line in xaml?

查看:22
本文介绍了您可以在 xaml 的 1 行内使用 Binding ValidationRule 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道用什么正确的措辞来描述我在这里要做的事情……所以我只是展示一下.

I don't know the correct wording to describe what I'm trying to do here... so I'll just show it.

我知道这个 xaml 有效:

This xaml I know works:

<TextBox>
  <TextBox.Text>
    <Binding Path="Location" UpdateSourceTrigger="PropertyChanged">
      <Binding.ValidationRules>
        <domain:NotEmptyValidationRule ValidatesOnTargetUpdated="True"/>
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>

但这很冗长.我想以类似的方式来做...

But this is pretty verbose. I would like to do it in a way similar to this...

<TextBox Text={Binding Path=Location, UpdateSourceTrigger=PropertyChanged,
                       ValidationRules={domain:NotEmptyValidationRuleMarkup ValidateOnTargetUpdated=True}}"/>

我创建了一个名为 NotEmptyValidationRuleMarkup 的类,它返回一个 NotEmptyValidationRule 的实例,它有点工作.项目构建得很好,运行得很好,一切都按照我的预期工作.但是,我无法再在设计器中查看我的窗口.它给了我一个无效标记错误,因为 属性ValidationRules"没有可访问的 setter..确实,ValidationRules 没有设置器.如果我尝试通过 C# 中的代码设置 ValidationRules,则会出现编译错误.但是由于某种原因,当我在 XAML 中分配它时,它实际上确实构建和运行得很好.我糊涂了.有没有一种方法可以让我在不提升窗口设计视图的情况下完成这项工作?

I made a class called NotEmptyValidationRuleMarkup that returns an instance of NotEmptyValidationRule, and it sort-of works. Project builds just fine, it runs just fine, everything works exactly as I expect it to. However, I can no longer view my window in the designer. It gives me an Invalid Markup error because The property "ValidationRules" does not have an accessible setter.. And it's true, ValidationRules does not have a setter. If I try to set ValidationRules through code in C# I get a compile error. But for some reason when I assign it in XAML it actually does build and run just fine. I'm confused. Is there a way I can make this work without jacking up the design view of my window?

推荐答案

即使 xaml 解释器碰巧将标记扩展变成了一些有效的东西,但这并没有得到真正的支持.

Even though the xaml interpreter happens to turn the markup extension into something working, this is not really supported.

请参阅 MSDN - 绑定标记扩展

以下是无法使用 Binding 标记扩展/{Binding} 表达式形式设置的 Binding 属性.

The following are properties of Binding that cannot be set using the Binding markup extension/{Binding} expression form.

  • ...

ValidationRules:该属性采用 ValidationRule 对象的通用集合.这可以表示为 Binding 对象元素中的属性元素,但没有现成的属性解析技术可用于 Binding 表达式.请参阅 ValidationRules 的参考主题.

ValidationRules: the property takes a generic collection of ValidationRule objects. This could be expressed as a property element in a Binding object element, but has no readily available attribute-parsing technique for usage in a Binding expression. See reference topic for ValidationRules.

但是,让我建议一种不同的方法:不要在绑定中嵌套自定义标记扩展,而是将绑定嵌套在自定义标记扩展中:

However, let me suggest a different approach: instead of nesting the custom markup extension in the binding, nest the binding in a custom markup extension:

[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);
    }
}

并使用如下:

<TextBox Text="{local:BindingEnhancementMarkup {Binding Path=Location, UpdateSourceTrigger=PropertyChanged}}"/>

当然,对于生产环境,您可能希望在标记扩展中添加更多检查,而不是假设一切都已就绪.

Ofcourse, for production you may want to add a few more checks in the markup extension instead of just assuming everything is in place.

这篇关于您可以在 xaml 的 1 行内使用 Binding ValidationRule 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆