WPF MVVM ScrollIntoView

标签 wpf xaml mvvm listbox

我有两个列表框的 View :

列表框 1 元素:A、B、C。
列表框 2 元素:...、A、...、B、...、C、...(长列表)。

当用户在列表框 1 中选择一个元素时,我想在列表框 2 中也将相同的元素滚动到 View 中(而不是选择)。

在我的 View 模型中,我有一个绑定(bind)到列表框 2 的 SelectedItem 的属性。但是如何将该元素滚动到列表框 2 的 View 中?
当然我不能在我的虚拟机中做 listbox.ScrollIntoView(selectedItem) 。

用 MVVM 模式解决这个问题的最佳解决方案是什么?

最佳答案

您可以通过一种行为来做到这一点,一个简单的解决方案根本不涉及 VM:

public static class ScrollToSelectedBehavior
{
    public static readonly DependencyProperty SelectedValueProperty = DependencyProperty.RegisterAttached(
        "SelectedValue",
        typeof(object),
        typeof(ScrollToSelectedBehavior),
        new PropertyMetadata(null, OnSelectedValueChange));

    public static void SetSelectedValue(DependencyObject source, object value)
    {
        source.SetValue(SelectedValueProperty, value);
    }

    public static object GetSelectedValue(DependencyObject source)
    {
        return (object)source.GetValue(SelectedValueProperty);
    }

    private static void OnSelectedValueChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var listbox = d as ListBox;
        listbox.ScrollIntoView(e.NewValue);
    }
}

你会像这样使用它:
<ListBox x:Name="lb1" ItemsSource="{Binding Items}" />
<ListBox x:Name="lb2" ItemsSource="{Binding Items}" behaviors:ScrollToSelectedBehavior.SelectedValue="{Binding ElementName=lb1, Path=SelectedValue}"/>

更好的解决方案是将行为的 DP 绑定(bind)到 VM 中的一个对象,该对象在 listbox1 中的选定值更改时引发一个事件。这会将这个特性暴露给 VM 代码,并允许进行单元测试等。

关于WPF MVVM ScrollIntoView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33597483/

相关文章:

c# - 在没有 setter 的情况下通知属性更改事件

wpf - 滚动时触发 DataGrid SelectionChanged 事件

c# - 找不到类型或命名空间名称(XAML 新增功能)

c# - 使用 DataTemplate 将 View 绑定(bind)到 ViewModel 时出现问题

使用 Unity 进行 MVVM 依赖注入(inject),用于分层 View 模型

WPF DataGrid 图标和 bool 值

c# - 动态添加标签到 DevExpress DXTabControl WPF, MVVM

c# - 将项目从 Xaml 文件添加到字典属性

xaml - 如何在 Win10 通用应用程序中禁用 GridView/ListView 上的倾斜动画?

mvvm - Xamarin.Forms 控件模板绑定(bind)不起作用