How to execute ScrollIntoView after changing filter in ListView in MVVM application (WPF)?

I have an ObservableCollection in a virtual machine that appears in a view in a ListView. When the selected item changes, the SelectionChanged event fires beautifully. The following is an example of setting ListView:

<ListView Grid.Row="3" Margin="5" AlternationCount="2" Name="_lvSettings" 
          IsSynchronizedWithCurrentItem="True"
          ItemsSource="{Binding Path=CollectionView}" 
          SelectedIndex="{Binding Path=SelectedSettingIndex}"
          SelectionChanged="OnSelectionChanged"  >
    <ListView.View>
        <GridView>
            <GridViewColumn Width="170" 
                            Header="{Binding Path=ShowAllDisplay}"
                            x:Name="_colSettings"  
                            DisplayMemberBinding="{Binding Path=Setting}"/>
            <GridViewColumn Header="Old Value" Width="150" 
                            DisplayMemberBinding="{Binding Path=OldVal}"/>
            <GridViewColumn Header="New Value" 
                            DisplayMemberBinding="{Binding Path=NewVal}" />
        </GridView>
    </ListView.View>
</ListView>

The problem is that I am changing the filter to a collection. The selected item remains the same as good, but the ListView changes to display from the first item, and often the selected item is not displayed (but still the selected item).

VM "SelectedSettingIndex", PropertyChanged . (base.OnPropertyChanged( "SelectedSettingIndex" );) , , , , , . ScrollIntoView - , . ?

, , , :

1) CollectionViewSource VM .

2) .

3) , ListView 10 .

4) "" , 50 .

5) , .

: ListView , "A" , ListView "" , "A" .

: ListView , "A" , ListView "" 10 . "A" .

+3
4

SelectedItem ListView :

public MyTypeOfObject SelectedItem { get; set; }

XAML:

<ListView Name="MyListView" SelectedItem="{Binding SelectedItem}"...></ListView>

, , :

if (SelectedItem != null)
    MyListView.ScrollIntoView(SelectedItem);

EDIT:

, (ListView), CollectionView , , .

+1

MVVM, , viewModel, Mode=TwoWay... Selection ListView ( )

System.Windows.Interactivity, Behavior<T> class

public class ScrollIntoViewForListView : Behavior<ListView>
{
    /// <summary>
    ///  When Beahvior is attached
    /// </summary>
    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
    }

    /// <summary>
    /// On Selection Changed
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void AssociatedObject_SelectionChanged(object sender,
                                           SelectionChangedEventArgs e)
    {
        if (sender is ListView)
        {
            ListView listview = (sender as ListView);
            if (listview.SelectedItem != null)
            {
                listview.Dispatcher.BeginInvoke(
                    (Action) (() =>
                                  {
                                      listview.UpdateLayout();
                                      if (listview.SelectedItem !=
                                          null)
                                          listview.ScrollIntoView(
                                              listview.SelectedItem);
                                  }));
            }
        }
    }
    /// <summary>
    /// When behavior is detached
    /// </summary>
    protected override void OnDetaching()
    {
        base.OnDetaching();
        this.AssociatedObject.SelectionChanged -=
            AssociatedObject_SelectionChanged;

    }
}

XAML xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

Control                                                                                                                   DisplayMemberBinding = "{Binding Path = Setting}" /" >                                                   

, "MySelectedItem" ViewModel, , .

viewModel INotifyProperty, , xaml, viewModel View...

SelectionChanged MVVM

MVVM " SelectionCnaged", Setter of MySelectedItem, EventToCommand .

Google ColletionViewSource , , ..etc

, ...

+10

(), :

:

public class SelectingItemAttachedProperty
{
    public static readonly DependencyProperty SelectingItemProperty = DependencyProperty.RegisterAttached(
        "SelectingItem",
        typeof(int),
        typeof(SelectingItemAttachedProperty),
        new PropertyMetadata(default(int), OnSelectingItemChanged));

    public static int GetSelectingItem(DependencyObject target)
    {
        return (int)target.GetValue(SelectingItemProperty);
    }

    public static void SetSelectingItem(DependencyObject target, int value)
    {
        target.SetValue(SelectingItemProperty, value);
    }

    static void OnSelectingItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var lb = sender as ListBox;
        if (lb?.SelectedItem == null)
            return;

        lb.Dispatcher.InvokeAsync(() =>
        {
            lb.UpdateLayout();
            lb.ScrollIntoView(lb.SelectedItem);
        });
    }
}

:

<Listbox
    design:SelectingItemAttachedProperty.SelectingItem="{Binding CollectionViewFromVM.Count}"
   ...>

=)

+1

- 2 , , 100% :

1) ViewModel, , . ScrollToView . VM VM-, - , ViewModel .

2) ScrollToView ListView LayoutUpdated. , - .

. , .

0

All Articles