Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF MVVM ScrollIntoView

I have a view with two listboxes:

Listbox 1 elements: A, B, C. Listbox 2 elements: ..., A, ..., B, ..., C, ... (long list).

When the user selects an element in listbox 1, I want to scroll the same element into view (not select) also in listbox 2.

In my viewmodel I have a property bound to the SelectedItem of Listbox 2. But how can I scroll that element into view of listbox 2? Of course I cannot do listbox.ScrollIntoView(selectedItem) in my VM.

What's the best solution to solve this problem with the MVVM pattern?

like image 977
TWT Avatar asked Nov 08 '15 18:11

TWT


1 Answers

You can do this with a behavior, a simple solution wouldn't involve the VM at all:

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);
    }
}

Which you would use like this:

<ListBox x:Name="lb1" ItemsSource="{Binding Items}" />
<ListBox x:Name="lb2" ItemsSource="{Binding Items}" behaviors:ScrollToSelectedBehavior.SelectedValue="{Binding ElementName=lb1, Path=SelectedValue}"/>

A slightly better solution would be to instead bind the behavior's DP to an object in the VM which raises an event whenever the selected value in listbox1 changes. That would expose this feature to the VM code and also allow for unit testing etc.

like image 108
Mark Feldman Avatar answered Sep 19 '22 14:09

Mark Feldman