WPF, как мне вызвать ListBox.ScrollIntoView, используя шаблон MVVM? - PullRequest
0 голосов
/ 22 января 2019

У меня есть приложение WPF, в котором содержимое ListBox обновляется, когда пользователь нажимает кнопку.Первоначальной проблемой была переориентация ListBox на конкретное значение SelectedIndex, которое привязано к свойству ActiveItem в моей ViewModel.Мне удалось решить эту проблему с помощью следующего кода:

XAML:

<ListBox ItemsSource="{Binding ListOfItems}" SelectedIndex="{Binding ActiveItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                 IsSynchronizedWithCurrentItem="True"  SelectionChanged="ListBox_SelectionChanged" x:Name="ListBoxSelector">

Кодовый код:

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ListBoxSelector.ScrollIntoView(ListBoxSelector.SelectedItem);
    }

Однако в настоящее время у меня есть вышеуказанный код- в файле MainWindow.xaml.cs вместо моего ViewModel.У меня вопрос, как мне переместить этот код в ViewModel, чтобы я мог придерживаться шаблона MVVM?Я не могу понять, как правильно обращаться к свойству ScrollIntoView ListBox из ViewModel.

Ответы [ 4 ]

0 голосов
/ 24 января 2019

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

public class perListBoxHelper : Behavior<ListBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
        base.OnDetaching();
    }

    private static void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var listBox = sender as ListBox;

        if (listBox?.SelectedItem == null)
            return;

        Action action = () =>
        {
            listBox.UpdateLayout();

            if (listBox.SelectedItem != null)
                listBox.ScrollIntoView(listBox.SelectedItem);
        };

        listBox.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
    }
}

Подробнее о моем блоге .

Кроме того, лично я связывался бы с SelectedItem ListBox, а не SelectedIndex, и обрабатывал бы любую обработку при выборе элемента в этом установщике свойств, а не использовал бы обработчик событий.

0 голосов
/ 22 января 2019

Я не уверен, что мое решение - шаблон MVVM. Но с такой проблемой это может решить проблему.

Вот что я сделаю: если нажать кнопку, она вызовет команду дляВызовите метод во ViewModel. Когда ViewModel завершит свою работу, viewModel вызовет пользовательское событие (где включает индекс элемента, в который должен прокручиваться список).И до того, как это произойдет, когда View is Loaded, Code View-View должен прослушать его ViewModel через DataContext View и выполнить scrollIntoView.

Как я уже сказал, я не уверен, что это MVVM-путь, но я подумалэто приемлемо.

0 голосов
/ 22 января 2019

Не существует универсального решения для каждого запроса по этому поводу, и, как другие уже упоминали, MVVM не означает, что нет никакого кода позади, но нет ненужного кода позади.

Однако в вашем конкретном запросе есть решение, если вы не хотите, чтобы за ним был код - создайте класс, который наследует от ListView и обрабатывает запрос так, как вы хотите, чтобы он обрабатывался, и затем используйте его в своем XAML.

0 голосов
/ 22 января 2019

Шаблон MVVM не исключает использование кода позади. На самом деле, это невозможно, потому что в некоторых случаях код является правильным решением . Модель представления - это модель, а не замена представления. Другой способ думать об этом состоит в том, что модель представления содержит what , а представление содержит how . По крайней мере, это моя интерпретация модели MVVM.

В вашем случае what - это список предметов и текущий предмет. how - это сам ListBox и его поведение по умолчанию. Мне кажется, что прокрутка выбранного элемента в представлении является дополнительным поведением, и поэтому должна быть сохранена в представлении. Вы не нарушаете шаблон MVVM, потому что сохраняете what в модели представления и how в представлении.

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