2010-09-22 2 views
0

Я начал внедрять MVVM для одного из моих приложений Silverlight. (Я не использую инструментарий).MVVM viewmodel свойство triggering update

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

Каждый выбранный элемент combo привязан к объекту в моей модели. Установщик этих свойств повышает значение свойства INotifyPropertyChanged и автоматически обновляет данные, привязанные к сетке.

Все было в порядке, пока не понадобилось добавить кнопку сброса, целью которой является сброс параметров поиска. I .: в каждом поле со списком не должно указываться ни один элемент, и сетка должна быть пуста.

  • Если функция сброса в режиме просмотра обновляет поля поддержки, пользовательский интерфейс не будет отражать изменения, поскольку RaisePropertyChanged не будет вызываться.
  • Если функция сброса в ViewModel обновляет свойства, пользовательский интерфейс будет отражать изменения, но сетка будет обновляться дважды: когда переустановка первого свойства обнулить, а также для второго

Любой помощи приветствуется

/// <summary>Selected user.</summary> 
public User SelectedUser 
{ 
    get { return _selectedUser; } 
    set 
    { 
     _selectedUser = value; 
     RaisePropertyChanged("SelectedUser"); 

     UpdateProducts(); 
    } 
} 

/// <summary>Selected product category.</summary> 
public ProductCategory SelectedProductCategory 
{ 
    get { return _selectedProductCategory; } 
    set 
    { 
     _selectedProductCategory = value; 
     RaisePropertyChanged("SelectedProductCategory"); 

     UpdateProducts(); 
    } 
} 

// Reset option 1 
public void Reset() 
{ 
    _selectedUser = null; 
    _selectedProductCategory = null; 
    _products = null; 
} 

// Reset option 2 
public void Reset() 
{ 
    SelectedUser = null; 
    SelectedProductCategory = null; 
    // No need to update Products which has already been updated twice... 
} 

ответ

1

Это то, что действительно вызывает меня во многих рамках, включая WPF. Вам нужна некоторая концепция отсрочки ответа на уведомления об изменении, чтобы пользователь никогда не видел промежуточные состояния. Тем не менее, вы не можете изменить способ ответа WPF на ваши уведомления, поэтому самое лучшее, что вы можете сделать, это отложить уведомления до тех пор, пока «после того, как пыль не заселится». В вашем случае вы захотите изменить оба поля поддержки перед отправкой уведомлений. Ваш метод сброса может кодировать эту идею следующим образом:

public void Reset() 
{ 
    _selectedUser = null; 
    _selectedProductCategory = null; 
    _products = null; 

    RaisePropertyChanged("SelectedUser"); 
    RaisePropertyChanged("SelectedProductCategory"); 
} 

На моем взгляде, как WPF синхронно обновляет экран в ответ на уведомление изменения просто неправильно. Их система DependencyProperty дает им возможность просто отмечать зависимости как грязные и выполнять перерасчет позже.

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

+0

Спасибо за ваш ответ, я согласен с вами.Это не только теоретически «неверно», если мне удастся изменить имя свойств, рефакторинг не сможет обновить связанный с ним RaisePropertyChanged, это нормально, если они находятся в одном месте (средство настройки свойств), но мне кажется опасно, что они доступны в другом месте –

+0

Не начинайте меня с уведомлений об изменении свойств с помощью строк ... Ох, такой хрупкий и неэффективный. Вы думаете, что ребята из Microsoft, определяющие основные API, будут немного ярче. –

0

При использовании полей отступающие вы должны вызвать

RaisePropertyChanged("SelectedUser"); 
RaisePropertyChanged("SelectedProductCategory"); 

в методе Reset().

+0

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

1

Вы можете поднять один PropertyChanged событие для всех свойств после обновляются поля аккомпанемента:

RaisePropertyChanged(String.Empty); 
+0

Спасибо. Это наверняка обновит все элементы управления, даже те, которые не связаны с изменениями. Разве не весь мой пользовательский интерфейс «моргнет»? –

+0

Да, он обновит все, что связано с вашей моделью. Но я сомневаюсь, что вы сможете увидеть его «мигающим» ... –

Смежные вопросы