How to suppress validation when nothing is entered

前端 未结 8 1355
醉梦人生
醉梦人生 2020-12-13 04:40

I use WPF data binding with entities that implement IDataErrorInfo interface. In general my code looks like this:

Business entity:

p         


        
8条回答
  •  不知归路
    2020-12-13 04:57

    Damn this took a while to think out but as always,...attached behaviours to the rescue.

    What you're looking at in essence is dirty state tracking. There are many ways to do this using your ViewModel but since you didn't want to change your entities the best way is using behaviours.

    First off remove the ValidatesOnDataErrors from your Xaml binding. Create a behaviour for the control you're working on ( as shown below for TextBox ) and in the TextChanged event (or whatever event you want) reset the binding to one that does validate on data errors. Simple really.

    This way, your entities don't have to change, your Xaml is kept reasonably clean and you get your behaviour.

    Here's the behaviour code-

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    
        namespace IDataErrorInfoSample
        {
            public static class DirtyStateBehaviours
            {
    
    
                public static string GetDirtyBindingProperty(DependencyObject obj)
                {
                    return (string)obj.GetValue(DirtyBindingPropertyProperty);
                }
    
                public static void SetDirtyBindingProperty(DependencyObject obj, string value)
                {
                    obj.SetValue(DirtyBindingPropertyProperty, value);
                }
    
                // Using a DependencyProperty as the backing store for DirtyBindingProperty.  This enables animation, styling, binding, etc...
                public static readonly DependencyProperty DirtyBindingPropertyProperty =
                    DependencyProperty.RegisterAttached("DirtyBindingProperty", typeof(string), typeof(DirtyStateBehaviours),
                    new PropertyMetadata(new PropertyChangedCallback(Callback)));
    
    
                public static void Callback(DependencyObject obj,
                    DependencyPropertyChangedEventArgs args)
                {
                    var textbox = obj as TextBox;
                    textbox.TextChanged += (o, s) =>
                    {
                        Binding b = new Binding(GetDirtyBindingProperty(textbox));
                        b.ValidatesOnDataErrors = true;
                        textbox.SetBinding(TextBox.TextProperty, b);
                    };
    
                }
            }
        }
    

    And the Xaml is pretty straight forward too.

    
    
    
        
    
    
        
        
        

    HTH, Stimul8d.

提交回复
热议问题