【问题标题】:Text Binding to local property: Validation not working文本绑定到本地属性:验证不起作用
【发布时间】:2012-08-23 08:11:47
【问题描述】:

我是 WPF 新手,有一个(在我看来)奇怪的问题: 我想将本地属性(名称:XmlText)绑定到 TextBox.Text 属性并使用如下验证规则验证值:

<TextBox Height="23" Width="301" Margin="78,14,0,0" Name="tbXMLFile" HorizontalAlignment="Left" VerticalAlignment="Top" TextChanged="tbXMLFile_TextChanged">
    <TextBox.Style>
        <Style TargetType="{x:Type TextBox}">
            <Style.Triggers>
                <Trigger Property="Validation.HasError" Value="true">
                    <Setter Property="ToolTip"
                            Value="{Binding RelativeSource={RelativeSource Self},
                                            Path=(Validation.Errors),
                                            Converter={StaticResource ErrorsToStringConverter}}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
    <TextBox.Text>
        <Binding Path="XmlText" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:RegexValidationRule Dateiendung="xml"></local:RegexValidationRule>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

每当我的属性 XmlText 获得一个新值时,验证不会做任何事情,但如果我在我的 TextBox 中手动输入文本,它就会验证。

如果我删除 TextChanged-Event 或将以下代码添加到事件中,验证将不再起作用:

XmlText = ((TextBox)sender).Text;

有人可以解释为什么程序会这样吗?

【问题讨论】:

  • 您是否为您设置为 DataContext 的对象类实现了 INotifyPropertyChanged?在您的属性 XmlText 中,您应该在值更改时引发 PropertyChanged 事件...

标签: c# wpf validation binding


【解决方案1】:

真正的问题是 ValidationRules:它们不是为按照您的想法而设计的! 看看这篇文章,了解更多详情:http://msdn.microsoft.com/en-us/library/system.windows.controls.validationrule.aspx

(当您使用 WPF 数据绑定模型时,您可以将 ValidationRules 与您的绑定对象相关联。要创建自定义规则,请创建此类的子类并实现 Validate 方法。可选地,使用内置的 ExceptionValidationRule,它会捕获源更新期间引发的异常,或 DataErrorValidationRule,它检查源对象的 IDataErrorInfo 实现引发的错误。 绑定引擎每次将输入值(即绑定目标属性值)传输到绑定源属性时,都会检查与绑定关联的每个 ValidationRule。)

如果您在绑定对象的类中实现System.ComponentModel.IDataErrorInfo 接口,您将捕获任何验证(分配绑定属性以及从 UI 分配)。

它们只是两种方法,我向您展示一个带有您的属性的示例:

public class TestObject : INotifyPropertyChanged, IDataErrorInfo
{
    private string _xmlText;

    public string XmlText
    {
        get
        {
            return _xmlText;
        }
        set
        {
            if (value != _xmlText)
            {
                _xmlText = value;
                NotifyPropertyChanged("XmlText");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void NotifyPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }


    public string Error
    {
        get { throw new NotImplementedException(); }
    }

    public string this[string columnName]
    {
        get
        {
            string result = null;
            if (columnName == "XmlText")
            {
                if (XmlText.Length > 5)
                    result = "Too much long!";
            }
            return result;
        }
    }
}

现在您的绑定验证应该可以正常工作了:

<TextBox.Text>
    <Binding Path="XmlText"
             UpdateSourceTrigger="PropertyChanged"
             ValidatesOnDataErrors="True"
             Mode="TwoWay" />
    </Binding>
</TextBox.Text>

【讨论】:

  • 感谢您的帮助 :) 问题是,我忘记设置 Binding-Mode = "TwoWay"...之后一切正常,即使没有 TextChanged-Event^^ 所以这可以标记为已解决:)
  • 非常好 :)...它是否也适用于 ValidationRule?还是使用 IDataErrorInfo?
猜你喜欢
  • 2015-04-10
  • 2011-01-28
  • 1970-01-01
  • 1970-01-01
  • 2014-11-20
  • 1970-01-01
  • 2020-03-03
  • 2017-07-26
  • 1970-01-01
相关资源
最近更新 更多