2013-05-08 4 views
1

Я использую шаблон MVVM (с MVVM Light) для создания моего приложения XAML (win8). У меня есть ListView, который привязан к свойству ViewModel. У меня также есть кнопка, которая запускает операцию над этим ViewModel, которая обновляет это свойство (что приводит к обновлению ListView). Кнопка использует команду для выполнения операции в ViewModel. Все идет нормально.MVVM pattern - выполнение операций просмотра

Проблема в том, что после обновления списка мне нужно выполнить операцию, которая строго принадлежит моему представлению, а не ViewModel. Он должен прокрутить список к определенному элементу. Как запустить эту операцию? Должен ли я использовать конкретное событие ListView?

ответ

1

Используя метод EventHandler и ScrollIntoView(Object), вы можете достичь того, чего хотите, без использования ссылок на View в ViewMovel и с учетом шаблона MVVM.

Создать событие в вашей ViewModel, как это:

public event EventHandler ScrollListView; 

На ваш взгляд добавить функцию обратного вызова для прокрутки ListView, когда свойство обновляется:

ViewModel vm; 
vm.ScrollListView += (sender, e) => 
{ 
    var specificItem = **some item**; 
    MyListView.SelectedItem = specificItem; 
    MyListView.UpdateLayout(); 
    MyListView.ScrollIntoView(MyListView.SelectedItem); 
}; 

Затем в ViewModel при обновлении это свойство и хотите прокрутить ListView:

if (this.ScrollListView != null) 
{ 
    this.ScrollListView(this, EventArgs.Empty); 
} 

Так я обычно делаю с некоторыми трюками для каждого случая, конечно.

1

ViewModel должен отделить код пользовательского интерфейса от дизайна пользовательского интерфейса (например, XAML). [Разделение проблем дизайнера и разработчика, автоматическое тестирование кода пользовательского интерфейса и т. Д.)

В идеале файл с обратным кодом для представления будет пустым (кроме вызова InitializeComponent), и вся логика и состояние пользовательского интерфейса будут обрабатываться ViewModel. Однако на практике могут быть некоторые специфические манипуляции с пользовательским интерфейсом, которые не могут обрабатываться только привязкой данных, и вам нужно будет прибегнуть к коду. Такой код следует помещать в код.

В вашем случае логика для (a) когда и (b) какой элемент прокрутки должен находиться в ViewModel (не в представлении). Только любая дополнительная логика, необходимая для выполнения фактической прокрутки в ListView, будет находиться в представлении «Код».

Да, мероприятие было бы идеальным способом сделать это, чтобы избежать каких-либо ссылок на представление внутри ViewModel. Однако я рекомендовал бы создать настраиваемое событие в ViewModel (например, OnFirstItemInViewChanged с аргументами элемента для прокрутки) и в регистре View code-behind для этого события и просто вызвать ListView.ScrollIntoView (элемент).

Примечание: У WinForms DataGridView было свойство FirstDisplayedScrollingRowIndex. Если в WPF ListView было что-то похожее, вы можете решить эту проблему, привязав это свойство к свойству ViewModel, в результате чего код-код полностью очистится.

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