WPF MVVM ScrollIntoView

时间:2015-11-08 18:31:21

标签: wpf xaml mvvm listbox

我有两个列表框的视图:

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

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

在我的viewmodel中,我有一个绑定到Listbox 2的SelectedItem的属性。但是如何将该元素滚动到列表框2的视图中? 当然我不能在我的VM中执行listbox.ScrollIntoView(selectedItem)。

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

1 个答案:

答案 0 :(得分:2)

您可以通过行为执行此操作,简单的解决方案根本不涉及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绑定到VM中的对象,只要listbox1中的选定值发生更改,就会引发事件。这会将此功能暴露给VM代码,并允许进行单元测试等。