我的第一个C# WPF ValidationRule没有触发。

3

我正在尝试学习如何实现数据验证,但我的第一次尝试没有触发lblSource_Error事件;有人知道我错过了什么吗?

我的Window XAML:

<Window x:Class="cCompleteWPFResourcesExamples.wValidationRule"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:cCompleteWPFResourcesExamples"
    Title="wValidationRule" Height="300" Width="300">
<Window.Resources>
    <local:Customer x:Key="rCustomer" Forename="InXaml" Surname="Created" ID="1"     
AmountOutstanding="0"/>
</Window.Resources>
<StackPanel x:Name="stkMain" DataContext="{StaticResource rCustomer}">
    <Label x:Name="lblSource" Validation.Error="lblSource_Error">
        <Label.Content>
            <Binding Path="ID" NotifyOnValidationError="True">
                <Binding.ValidationRules>
                    <local:cIDValidationRule/>
                </Binding.ValidationRules>
            </Binding>
        </Label.Content>
    </Label>
    <Label x:Name="lblErrorMessage" Content="No Error Yet"/>
</StackPanel>
</Window>

我的Windows代码:

   namespace cCompleteWPFResourcesExamples
    {
    /// <summary>
    /// Interaction logic for wValidationRule.xaml
    /// </summary>
    public partial class wValidationRule : Window
    {
        Customer cus = new Customer();

        public wValidationRule()
        {
            InitializeComponent();
            cus.ID = 0;
            stkMain.DataContext = cus;
        }


        private void lblSource_Error(object sender, ValidationErrorEventArgs e)
        {
            lblErrorMessage.Content = e.Error.ErrorContent.ToString();
        }
    }
    }

我的验证规则:

using System.Windows.Controls;

namespace cCompleteWPFResourcesExamples 
{
public class cIDValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, 
System.Globalization.CultureInfo cultureInfo)
    {
        int iValue = (int)value;
        if (iValue == 0) return new ValidationResult(false, "No ID number");

        return new ValidationResult(true, null);
    }
}
}

客户对象非常简单:只有几个属性。
谢谢!
詹姆斯

标签?标签不是输入,因此我认为验证对它们不起作用... - user1228
你自定义对象的id字段可以在表单上编辑还是只是显示?当你修改值时,验证规则将被检查。 - Salvatore Sorbello
2个回答

2

哎呀,这个标题好悲伤啊 :) :) 首先,wpf validationrule没有按照你想要的方式工作。

每当输入值(绑定目标属性值)传输到绑定源属性时,绑定引擎都会检查与绑定关联的每个ValidationRule。

请记住:

您输入某些内容并将其保存到源中 => ValidationRule 将触发。

您想在标签中显示某些内容,并且该值从源传输到标签 => ValidationRule 永远不会触发。

如果您希望示例起作用,请使用TextBox并将Binding Mode设置为TwoWay,以便您可以输入内容,Binding将将键入的值保存到源中,从而导致ValidationRule触发。 :)


谢谢:两个答案都很好,但我使用了这个来帮助我完成大部分工作(因为它是第一个!):将标签更改为文本框,设置绑定模式=双向,但我还需要在Customer类中实现INotifyPropertyChanged,在cIDValidationRule中将值拆箱为字符串然后转换为整数。 - james pearce
@jamespearce,你不需要将标签更改为文本框。请查看我的更新。 - Squirrel5853
没错,你做对了 :) 最简单的演示方法是使用文本框并在里面输入一些有趣的东西,呵呵呵呵。 - dev hedgehog

0

我不得不这样做才能让它对我起作用,这是我从这个网站上获得的。

<Binding Path="ID" 
NotifyOnValidationError="True" 
ValidatesOnDataErrors="true" 
ValidatesOnExceptions="True" 
UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">

希望这可以帮到你,同时要注意传递给验证的object在我的情况下是一个string而不是一个int
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
    if (value is int)
    {
        int iValue = (int)value;
        if (iValue == 0) 
        {
            return new ValidationResult(false, "No ID number");
        }

        return new ValidationResult(true, null);
    }
    else if (value is string)
    { 
        string strValue = (string)value;
        if (String.IsNullOrEmpty(strValue) || strValue == "0")
        { 
            return new ValidationResult(false, "No ID number"); 
        }
    }

    return new ValidationResult(true, null);
}

* 更新 **

我忘记了还需要添加这个才能触发它

public wValidationRule()
{
    InitializeComponent();
    cus.ID = 0;
    stkMain.DataContext = cus;

    //trigger the validation.
    lblSource.GetBindingExpression(Label.ContentProperty).UpdateSource();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接