Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ValidationRules在值设置回有效值时未删除错误_C#_Wpf_Xaml_User Controls_Validationrules - Fatal编程技术网

C# ValidationRules在值设置回有效值时未删除错误

C# ValidationRules在值设置回有效值时未删除错误,c#,wpf,xaml,user-controls,validationrules,C#,Wpf,Xaml,User Controls,Validationrules,导言 我已经创建了一个DecimalTextBoxUserControl,其中包含了我需要进行的一些十进制验证,因此我不需要每次都重新创建验证,只需使用UserControl。此验证具有需要绑定的属性,因此我创建了dependencProperties,以便可以根据进行绑定 问题 控件的验证行为异常。当我在文本框中键入错误值时,它显示为错误。但是,当我尝试更改代码中的值时,文本框中显示的值保持不变 以下是我执行的导致此错误的步骤(在本例中,1是无效值): 加载表单,默认值为0 在文本框中输入1

导言

我已经创建了一个DecimalTextBox
UserControl
,其中包含了我需要进行的一些十进制验证,因此我不需要每次都重新创建验证,只需使用
UserControl
。此验证具有需要绑定的属性,因此我创建了
dependencProperties
,以便可以根据进行绑定


问题

控件的验证行为异常。当我在
文本框中键入错误值时,它显示为错误。但是,当我尝试更改代码中的值时,文本框中显示的值保持不变

以下是我执行的导致此错误的步骤(在本例中,1是无效值):

  • 加载表单,默认值为0
  • 在文本框中输入1(由于验证结果不正确,文本框变为红色
  • 在代码中,我将绑定到文本框的属性设置为0
  • 表单仍在红色文本框中显示1

  • 代码示例

    我准备了一个例子来演示这个问题,可以下载

    我会在这里发布一些代码,如果你想要更多,请告诉我

    验证TestControl的XAML

    <UserControl x:Class="WPFTestProject.ValidationTestControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:v="clr-namespace:WPFTestProject"
        x:Name="ValidationTest"
        Height="50" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>          
    
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
            <TextBlock Text="Type 'Banana' here: "></TextBlock>
            <TextBox MinWidth="100">
                <TextBox.Text>
                    <Binding ElementName="ValidationTest"  Path="Text" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" ValidatesOnDataErrors="True" ValidatesOnExceptions="True">
                        <Binding.ValidationRules>
                            <v:NotBananaValidationRule>
                                <v:NotBananaValidationRule.NotWhatBinding>
                                    <v:NotBananaBinding x:Name="NotBananaValidationBinding"></v:NotBananaBinding>
                                </v:NotBananaValidationRule.NotWhatBinding>
                            </v:NotBananaValidationRule>
                        </Binding.ValidationRules>
                    </Binding>
                </TextBox.Text>
            </TextBox>
            <TextBlock Text=" (the text will give error when = 'Banana')"></TextBlock>
        </StackPanel>
    </Grid>
    
    为绑定创建的ValidationRule和FrameWorkElement

     public class NotBananaValidationRule:ValidationRule
    {
        private NotBananaBinding _notWhatBinding;
        public NotBananaBinding NotWhatBinding
        {
            get { return _notWhatBinding; }
            set { _notWhatBinding = value; }
        }
    
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            string what = value.ToString();
    
            if(what == _notWhatBinding.NotWhat||string.IsNullOrEmpty(what))
                return new ValidationResult(false,
                           "Please enter a string that is not " + _notWhatBinding.NotWhat);
            else
                return new ValidationResult(true, null);
    
        }
    
    }
    
    
    public class NotBananaBinding : FrameworkElement
    {
        public static readonly DependencyProperty NotWhatProperty = DependencyProperty.Register(
          "NotWhat", typeof(string), typeof(NotBananaBinding), new UIPropertyMetadata());
    
        public string NotWhat
        {
            get { return (string)GetValue(NotWhatProperty); }
            set { SetValue(NotWhatProperty, value); }
        }
    
        public NotBananaBinding() { }
    }
    
    基本上,这段代码所做的是检查您是否键入了“Banana”,然后返回一个验证错误。该控件公开依赖项属性,因为我希望在使用该控件时能够绑定到它们。
    FrameworkElement
    NotBananaBinding允许我创建依赖项属性(因为它是一个
    DependencyObject
    ),所以我可以为验证绑定内容。ValidationRule有一个NotBananaBinding属性,存储依赖项属性并在validate方法中使用它

    我知道我的属性名有点糟糕,抱歉。问题是示例在显示错误方面做得很好。在我匆忙制作示例的过程中,我没有很好地命名变量。如果您发现代码糟糕,请下载示例


    到目前为止我所了解的情况

    基本上,这个问题似乎是由我没有实际更改值这一事实引起的

    即使我在属性上调用OnPropertyChanged,因为值没有不同,它也不会尝试重新评估验证

    很明显,我可以将该值更改为任意有效值,然后将其更改为我希望的值,这样就可以工作了,但我希望有某种方法可以手动获取调用验证,重新评估该值,然后进行更改,等等。来回更改它有点混乱


    结论

    我是否做错了什么(可能是因为我实现了Josh Smith帖子中的验证和绑定的方式)

    这仅仅是一个c#bug,还是行为的本意?如果是,那么为什么

    有什么优雅的方法可以解决它吗


    u_u

    验证阻止设置
    文本
    属性。在setter上放置一个断点,您将看到当您键入最后一个“a”时,它不会中断。如果您键入Bananan并单击Backspace并显示错误,则按下按钮,它将工作。验证确保您的属性中没有无效值。因此,我如果在出错时将其保存到数据库中,它不会保存无效值。

    发布代码确实有帮助-人们不想运行示例项目。尝试将问题减少到再现问题的尽可能少的代码。你永远不知道,你可能会自己解决问题。如果你在在其中键入另一个字符将重新计算验证规则,但我的问题是我无法在代码中将其设置为有效值。由于验证阻止绑定发生,我似乎无法在删除绑定时通过代码更改文本框中的值。我尝试将文本框的值设置回以前的值,但原因是属性的值已经是该值(因为验证不允许更改无效值)没有更改通知,文本框值也没有刷新。您是如何设置文本框上的文本以删除绑定的,因为我在文本框旁边放置了一个按钮,它是onclick事件。我将文本框的文本设置为Banan,并且更改值会不断触发setter。您下载了示例吗?这很好地解释了我的问题t、 我所做的是在文本框中键入Banana。然后按下按钮将文本更改回Banan,它不会更改,因为属性的值已经是Banan。由于它没有更改,文本框中显示的文本保持为Banana。当验证引发错误时,绑定会断开,因为文本框中的文本是displays Banana,但值是BananI下载的,否则我无法在文本框旁边放置按钮。设置文本框的值而不是属性的值。是的,但问题是在我的真实项目中,我使用MVVM,所以我无法访问文本框的值。该示例显示了我如何无法通过更改属性来通过代码完成此操作。在rEallity这是一个没有按钮的控件,我尝试使用控件绑定到的属性将文本设置回viewmodel中。文本框位于控件内部,因此我无法直接访问它。我想我可以公开一个方法将其更改回,但我不确定我是否喜欢这个想法。
     public class NotBananaValidationRule:ValidationRule
    {
        private NotBananaBinding _notWhatBinding;
        public NotBananaBinding NotWhatBinding
        {
            get { return _notWhatBinding; }
            set { _notWhatBinding = value; }
        }
    
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            string what = value.ToString();
    
            if(what == _notWhatBinding.NotWhat||string.IsNullOrEmpty(what))
                return new ValidationResult(false,
                           "Please enter a string that is not " + _notWhatBinding.NotWhat);
            else
                return new ValidationResult(true, null);
    
        }
    
    }
    
    
    public class NotBananaBinding : FrameworkElement
    {
        public static readonly DependencyProperty NotWhatProperty = DependencyProperty.Register(
          "NotWhat", typeof(string), typeof(NotBananaBinding), new UIPropertyMetadata());
    
        public string NotWhat
        {
            get { return (string)GetValue(NotWhatProperty); }
            set { SetValue(NotWhatProperty, value); }
        }
    
        public NotBananaBinding() { }
    }