繁体   English   中英

WPF,如何使用MVVM模式触发ListBox.ScrollIntoView?

[英]WPF, how do I trigger ListBox.ScrollIntoView using MVVM pattern?

我有一个WPF应用程序,当用户按下按钮时,ListBox的内容就会更新。 我最初的问题是将ListBox重新聚焦到特定的SelectedIndex值,该值绑定到ViewModel中的ActiveItem属性。 我可以使用以下代码解决此问题:

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模式? 我还不太清楚如何从ViewModel正确处理ListBox的ScrollIntoView属性。

您可以使用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的列表框,而不是SelectedIndex ,以及处理项目选择的任何处理该财产二传手,而不是使用事件处理程序。

MVVM模式不排除使用后面的代码。 实际上,这不可能,因为在某些情况下, 正确的做法是隐藏背后代码。 视图模型是一个模型,不是视图替换。 另一种思考方式是,视图模型包含内容 ,而视图包含方式 至少,这是我对MVVM模式的解释。

在你的情况下,是什么项目的列表和当前项目。 该是怎样ListBox本身和它的默认行为。 在我看来,将选定的项目滚动到视图中是一种额外的行为,因此应保留在视图中。 因为你保持什么视图模型和如何在视图中你不违反MVVM模式。

我不确定我的解决方案是否为MVVM模式。但是对于这样的问题,它可以解决问题。

我将执行以下操作:如果按下Button,它将触发一个命令调用ViewModel中的方法。当ViewModel完成其工作时,viewModel会抛出一个自定义事件(其中包括列表框应滚动到的项目索引)。 在此之前,加载View时,View的Code-behind应该通过View的DataContext侦听其ViewModel,然后执行scrollIntoView。

就像我说的那样,我不确定这是否是MVVM,但是我认为这是可以接受的。

没有针对每个请求的通用解决方案,正如其他人提到的那样,MVVM并不意味着没有代码,但也没有多余的代码。

但是,如果您不想要任何代码,则可以在您的特定请求中找到解决方案-创建一个从ListView继承并按需要处理请求的类,然后在XAML中使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM