Проверка WPF и управление стилями TextBox - PullRequest
3 голосов
/ 29 января 2010

Я создал свою собственную платформу валидации для WPF, используя аттестацию на основе атрибутов. Я застрял на последнем шаге, который должен выделить TextBox. На самом деле, он выделяет текстовые поля, но все текстовые поля зависят от одного свойства HasError.

public class RegistrationViewModel  : ViewModel
    {
        [NotNullOrEmpty("FirstName should not be null or empty")] 
        public string FirstName { get; set; }

        [NotNullOrEmpty("Middle Name is required!")]
        public string MiddleName { get; set; } 

        [NotNullOrEmpty("LastName should not be null or empty")] 
        public string LastName { get; set; }

        public bool HasError
        {
            get
            {
                **return Errors.Count > 0; // THIS IS THE PROBLEM** 
            }
        }

    }

А вот код XAML:

 <Style x:Key="textBoxStyle" TargetType="{x:Type TextBox}">                   

            <Style.Triggers>

                <DataTrigger Binding="{Binding Path=HasError}" Value="True">
                    <Setter Property="Background" Value="Red" />
                </DataTrigger>

            </Style.Triggers>

        </Style>

Проблема с приведенным выше кодом заключается в том, что он выделит все текстовые поля, использующие «textBoxStyle», даже если они действительны. Это связано с тем, что HasError проверяется не на основе отдельных свойств, а в целом.

Есть идеи?

ОБНОВЛЕНИЕ 1:

ViewModel содержит коллекцию ошибок:

 public class ViewModel : ContentControl, INotifyPropertyChanged
    {
        public static DependencyProperty ErrorsProperty; 

        static ViewModel()
        {
            ErrorsProperty = DependencyProperty.Register("Errors", typeof(ObservableCollection<BrokenRule>), typeof(ViewModel)); 
        }

        public ObservableCollection<BrokenRule> Errors
        {
            get { return (ObservableCollection<BrokenRule>)GetValue(ErrorsProperty); }
            set 
            { 
                SetValue(ErrorsProperty,value);
                OnPropertyChanged("HasError");
             }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

    }

ОБНОВЛЕНИЕ 2:

Мой механизм проверки:

public bool Validate(object viewModel)
        {
            _brokenRules = new List<BrokenRule>();

            // get all the properties 

            var properties = viewModel.GetType().GetProperties(); 

            foreach(var property in properties)
            {
                // get the custom attribute 

                var attribues = property.GetCustomAttributes(typeof (EStudyValidationAttribute), false); 

                foreach(EStudyValidationAttribute att in attribues)
                {
                    bool isValid = att.IsValid(property.GetValue(viewModel,null));

                    if(isValid) continue; 

                    // add the broken rule 

                    var brokenRule = new BrokenRule()
                                         {
                                             PropertyName = property.Name,
                                             Message = att.Message
                                         }; 

                    _brokenRules.Add(brokenRule);
                }

            }

            var list = _brokenRules.ToObservableCollection(); 

            viewModel.GetType().GetProperty("Errors").SetValue(viewModel,list,null);

            return (_brokenRules.Count() == 0); 
        }

Ответы [ 2 ]

6 голосов
/ 29 января 2010

Вы можете реализовать интерфейс IDataErrorInfo в ваших ViewModels и в XAML проверить вложенные свойства Validation.HasError на элементах для элементов управления с ошибкой проверки; это лучше, потому что это стандартный механизм в .Net.

<Style x:Key="textBoxStyle" TargetType="{x:Type TextBox}">                   

            <Style.Triggers>

                <DataTrigger Binding="{Binding Path=Validation.HasError}" Value="True">
                    <Setter Property="Background" Value="Red" />
                </DataTrigger>

            </Style.Triggers>

        </Style>

При привязке к свойству в TextBoxes необходимо установить для свойства привязки ValidatesOnDataError значение true.

<TextBox x:Name="someTextBox" Text="{Binding Path=someProperty, ValidatesOnDataErrors=True}">



public class ViewModel : ContentControl, INotifyPropertyChanged,IDataErrorInfo
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

        public string this[string propertyName]
        {
            get
            {
                return ValidateProperty(this,propertyName);
            }
        }

        public string Error
        {
            get
            {
                            return "";
            }
        }

    }

Вы даже можете использовать свой реализованный метод проверки, но проверить проверку по свойству.

0 голосов
/ 30 апреля 2011

Вас может заинтересовать WPF Application Framework (WAF) и примеры приложений BookLibrary и EmailClient . Они используют атрибуты проверки из пространства имен DataAnnotations вместе с интерфейсом IDataErrorInfo . Чтобы получить эту работу, вам понадобятся только две дополнительные строки кода в проверенных классах (например, BookLibrary.Domain / Book.cs).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...