WPF TextBox MaxLength - 有没有办法将它绑定到绑定字段上的数据验证最大长度?

mic*_*ael 10 c# wpf xaml maxlength data-annotations

视图模型:

public class MyViewModel
{
    [Required, StringLength(50)]
    public String SomeProperty { ... }
}
Run Code Online (Sandbox Code Playgroud)

XAML:

<TextBox Text="{Binding SomeProperty}" MaxLength="50" />
Run Code Online (Sandbox Code Playgroud)

有没有办法避免设置TextBox的MaxLength以匹配我的ViewModel(可能会因为它在不同的程序集中而改变)并让它根据StringLength要求自动设置最大长度?

McG*_*gle 17

我使用Behavior将TextBox连接到其绑定属性的验证属性(如果有).行为如下所示:

/// <summary>
/// Set the maximum length of a TextBox based on any StringLength attribute of the bound property
/// </summary>
public class RestrictStringInputBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        AssociatedObject.Loaded += (sender, args) => setMaxLength();
        base.OnAttached();
    }

    private void setMaxLength()
    {
        object context = AssociatedObject.DataContext;
        BindingExpression binding = AssociatedObject.GetBindingExpression(TextBox.TextProperty);

        if (context != null && binding != null)
        {
            PropertyInfo prop = context.GetType().GetProperty(binding.ParentBinding.Path.Path);
            if (prop != null)
            {
                var att = prop.GetCustomAttributes(typeof(StringLengthAttribute), true).FirstOrDefault() as StringLengthAttribute;
                if (att != null)
                {
                    AssociatedObject.MaxLength = att.MaximumLength;
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以看到,该行为只是检索文本框的数据上下文及其"Text"的绑定表达式.然后它使用反射来获取"StringLength"属性.用法是这样的:

<UserControl
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

    <TextBox Text="{Binding SomeProperty}">
        <i:Interaction.Behaviors>
            <local:RestrictStringInputBehavior />
        </i:Interaction.Behaviors>
    </TextBox>

</UserControl>
Run Code Online (Sandbox Code Playgroud)

您也可以通过扩展来添加此功能TextBox,但我喜欢使用行为,因为它们是模块化的.


eva*_*nko 0

一种方法是在同一视图模型中创建一个名为 SomePropertyMaxLength 的属性,然后将 MaxLength 属性绑定到该属性。

<TextBox Text="{Binding SomeProperty}" MaxLength="{Binding SomePropertyMaxLength}"/>
Run Code Online (Sandbox Code Playgroud)