2011-01-13 4 views
4

У меня есть два элемента управления, привязанные к свойствам MinCartValue и MaxCartValue. MinCartValue должен быть меньше MaxCartValue. Чтобы добиться этой проверки, я реализовал интерфейс IDataErrorInfo и выполнил вышеуказанную проверку в этом методе [columnName], если затронуты MinCartValue или MaxCartValue. ValidatesOnDataErrors = True устанавливается в привязке обоих элементов управления. Валидация работает правильно, выделяя каждый элемент управления, когда изменение его значения свойства нарушает правило. Проблема заключается в том, что после того, как элемент управления отмечен как недопустимый, если пользователь исправляет проблему, изменяя значение другого элемента управления, первый элемент управления помечается как недопустимый. Это понятно, потому что метод IDataErrorInfo не выполнял проверку на свойство первого элемента управления.S/L 4 & IDataErrorInfo - Как принудительно повторить проверку элемента управления (при касании связанного элемента управления)

Так что мне нужно, чтобы свойство # 1 было повторно проверено (или способ очистки недопустимого состояния), когда свойство # 2 проверено, и наоборот. Я попытался вызвать RaisePropertyChanged в моем методе [columnName], но он ничего не делает. Также попробовал установить свойство на свое значение, чтобы попытаться обмануть его, чтобы проверить себя, но опять ничего не происходит.

Благодаря

ответ

2

Я бы рекомендовал смотреть на интерфейс INotifyDataErrorInfo (введен в Silverlight 4). Он может асинхронно уведомлять, если свойства становятся недействительными, поэтому я считаю, что структура лучше относится к этому во многих свойствах, а не к ожиданию того, что свойство, которое в настоящее время изменяется, является единственным, действие которого может изменяться.

+0

OK Я посмотрю на это. – Laurence

+0

Почему же 'INotifyDataErrorInfo' не в WPF? Такой полезный интерфейс! –

0

Я не уверен, что я точно понимаю вашу проблему, но, возможно, это может помочь. Предоставление некоторого примера XAML и кода свойства привязки поможет.

Это звучит как проблема вашего кода в зависимости от установленного по умолчанию UpdateSourceTrigger, который в случае элементов управления TextBox является их фокусом/нефокусировкой. Вы можете установить в XAML атрибут UpdateSourceTrigger, добавив UpdateSourceTrigger = Explicit к вашей привязке, где выполняется ваша проверка. Затем в каждом текстовом поле (MinCartValue, MaxCartValue) добавьте обработчик события в событие TextChanged.

В отделенном коде в обработчик событий, вы можете сделать что-то вроде этого:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) 
    { 
     TheTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource(); 
    } 

TheTextBox в этом случае будет один из элементов управления корзиной. Метод UpdateSource() - это способ вручную обновить значение привязки, которое должно инициировать вашу проверку. Этот метод позволяет избежать привязки к триггеру для обновления значений и изменения свойств, которые были изменены за пределами области по умолчанию (с использованием текста, измененного с учетом фокуса и нецелевого использования TextBox в этом случае).

+0

Спасибо. Я должен был упомянуть, что я использую подход MVVM, где «код сзади» не имеет ссылок на элементы управления XAML. Я хотел бы придерживаться этого, поэтому я ищу способ сделать это, только ссылаясь на свойства объекта, действующего как контекст данных. – Laurence

+0

Да, я не знал, используете ли вы MVVM или нет. Я стараюсь следовать за MVVM самостоятельно, но я пока не придумал хорошего решения MVVM для этой проблемы. – avanek

0

Вот как я решил это. Предположим, что Property1 и Property2 являются зависимыми. Я не знаком с MVVM (пока), но вы, вероятно, расширяете свой класс сущностей для реализации IDataErrorInfo. В этом случае вы также можете продлить на [Property] Изменен метод и отчет об изменениях в созависимых собственности:

partial class YourEntity : IDataErrorInfo 
{ 
    public string this[string columnName] 
     { 
      //Your validation logic 
     } 

    public string Error 
    { 
     //WPF doesn't use it anyway 
     get { return string.Empty; } 
    } 

    partial void OnProperty1Changed() 
    { 
     OnPropertyChanging("Property2"); 
     OnPropertyChanged("Property2"); 
    } 

    partial void OnProperty2Changed() 
    { 
     OnPropertyChanging("Property1"); 
     OnPropertyChanged("Property1"); 
    } 
} 

В этом случае обновление в любом из этих свойств делает оба связаны управления переоценивать себя.

EDIT2: Кажется, вы должны использовать OnPropertyChang * вместо ReportPropertyChang *. ReportPropertyChanged уведомит инфраструктуру сущности, что ожидающие изменения в модели, но на самом деле все, что вы пытаетесь сделать, это сообщить о представлении. Вы не хотите обновлять базу данных с помощью свойства, которое на самом деле не изменилось. ReportPropertyChang * также терпит неудачу в вычисленных полях, которые не имеют сопоставлений в базе данных. EDIT1: выяснено, что необходимо вызвать ReportPropertyChanging перед ReportPropertyChanged.

+0

Спасибо, но ReportPropertyChanged недоступен в моем проекте. Является ли он частью платформы Entity Framework? – Laurence

+0

Да, это защищенный метод EntityObject. Вначале я не понял, что ваш запрос был посвящен Silverlight. Я работаю с WPF, не уверен, как это соотносится с SL. – Andikki

1

У меня было два свойства DateTime (DateFrom и DateTo), которые необходимо было проверить друг против друга. В сеттерах для этих свойств я просто поднял событие PropertyChanged как для DateTo, так и для DateFrom. Работал как шарм.

+0

Хороший простой ответ! – Laurence