开发者

Binding ValidationRules in one line?

开发者 https://www.devze.com 2023-01-06 21:12 出处:网络
I have several one-line binding already written and I\'d like to keep it that way if possible and if it still is humanly readable.

I have several one-line binding already written and I'd like to keep it that way if possible and if it still is humanly readable. Is there any way to rewrite this

<TextBox.Text>
    <Binding Path="SomePath" NotifyOnValidationError="True" >
        <Binding.ValidationRules>
            <local:ValidationRule1></local:ValidationRule1>
        </Binding.ValidationRules>
    </Binding>
</TextBox.Text>

in one line?, like

<TextBox Text="{Binding Path=SomePath, [V开发者_开发问答alidationRule1...]}" />


I think there is no one-liner and besides the standard version is more readable.


There is no one-liner out of the box, but it's perfectly possible to make one yourself by taking advantage of markup extensions. More specifically, create a custom method of defining bindings for typical scenarios in your project.

A useful thing to note is that Binding class is itself a markup extension and thus provides an implementation of ProvideValue. It means that a custom binding markup extensions can just create or take a binding, fill out its values as needed and provide the value by the newly modified binding.

For example, if you commonly use a single validation rule and want to keep it in a one-liner, you may want to create an extension like this:

using System;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Markup;

namespace MyProject.Markup
{
    public class SingleValidationBindingExtension : MarkupExtension
    {
        private Binding _binding;

        public SingleValidationBindingExtension(Binding binding, ValidationRule validationRule)
        {
            _binding = binding;
            _binding.ValidationRules.Add(validationRule);
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return _binding.ProvideValue(serviceProvider);
        }
    }
}

Then, somewhere in your XAML:

<UserControl xmlns:ext="clr-namespace:MyProject.Markup;assembly=MyProject"
             ...>
    <UserControl.Resources>
        <local:ValidationRule1 x:Key="ValidationRule1"/>
    </UserControl.Resources>

    <!-- Note that you can customize other binding properties within the inner {Binding ...} markup -->
    <TextBox Text="{ext:SingleValidationBinding {Binding SomePath}, {StaticResource ValidationRule1}}" />

</UserControl>

Voilà! Now it took only one line to apply the validation rule to the binding.

Granted, having an extension specifically for a single-validation bindings may seem wasteful. However, with this simple proof-of-concept it's easy to expand upon the idea of custom binding markups. For example, you may group commonly used combinations of converters and validations rules into objects, define them as static resources and then apply them to bindings using a custom binding definition.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号