在更改选定索引||时显示列表框中的选定项目滚动列表框

在更改选定索引||时显示列表框中的选定项目滚动列表框

问题描述:

我有一个列表框显示在其中的书籍。 SelectedIndexCurrentindex绑定到视图模型中的属性。 Underneeth ListBox是两个按钮,这就是Viewmodel中的SelectedIndex属性的简单添加(下一个)或减去(最后)一个按钮。在更改选定索引||时显示列表框中的选定项目滚动列表框

<DockPanel LastChildFill="False"> 
    <ListBox DockPanel.Dock="Top" 
      ItemsSource="{Binding Books, Mode=OneWay}" 
      SelectedItem="{Binding CurrentBook, Mode=TwoWay}" 
      SelectedIndex="{Binding SelectedIndex}" 
      /> 
    <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom"> 
     <Button Content="Last" Command="{Binding ChangeBook}" CommandParameter="last"/> 
     <Button Content="Next" Command="{Binding ChangeBook}" CommandParameter="next"/> 
    </StackPanel> 
</DockPanel> 

击中NextLast按钮改变ListBox的指数。没有发生的事情是,当索引向用户出现可见区域时,ListBox不会向下滚动,保持选定的索引可见。

我想知道如何实现,SelectedItem总是可见的列表框中,除非用户滚动。
当然,我想要做到这一点,而不是打破MVVM模式,而这样做。

下面是如何做到这一点,而不违反MVVM。

<ListBox DockPanel.Dock="Top" 
     ItemsSource="{Binding Books, Mode=OneWay}" 
     SelectedItem="{Binding CurrentBook, Mode=TwoWay}" 
     SelectedIndex="{Binding SelectedIndex}" 
     SelectionChanged="ListBox_SelectionChanged" 
     /> 

后面的代码:

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    var lb = (ListBox)sender; 

    lb.ScrollIntoView(lb.SelectedItem); 
} 

而这里做一个更体面的方式。没有什么错误使用后面的代码来处理这种事情,但是如果像这样的行为将在不同的视图中多次使用,使用附加属性比复制和粘贴事件处理函数更方便。此外,它现在可以用于像DataTemplate这样的上下文,其中可能没有代码。

预先提供了一些代码,但您可以轻松地将附加属性添加到项目中的任何ListBox

public static class ListBoxExtensions 
{ 
    #region ListBoxExtensions.KeepSelectedItemVisible Attached Property 
    public static bool GetKeepSelectedItemVisible(ListBox lb) 
    { 
     return (bool)lb.GetValue(KeepSelectedItemVisibleProperty); 
    } 

    public static void SetKeepSelectedItemVisible(ListBox lb, bool value) 
    { 
     lb.SetValue(KeepSelectedItemVisibleProperty, value); 
    } 

    public static readonly DependencyProperty KeepSelectedItemVisibleProperty = 
     DependencyProperty.RegisterAttached("KeepSelectedItemVisible", typeof(bool), typeof(ListBoxExtensions), 
      new PropertyMetadata(false, KeepSelectedItemVisible_PropertyChanged)); 

    private static void KeepSelectedItemVisible_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var lb = (ListBox)d; 

     if ((bool)e.NewValue) 
     { 
      lb.SelectionChanged += ListBox_SelectionChanged; 
      ScrollSelectedItemIntoView(lb); 
     } 
     else 
     { 
      lb.SelectionChanged -= ListBox_SelectionChanged; 
     } 
    } 

    private static void ScrollSelectedItemIntoView(ListBox lb) 
    { 
     lb.ScrollIntoView(lb.SelectedItem); 
    } 

    private static void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     ScrollSelectedItemIntoView((ListBox)sender); 
    } 
    #endregion ListBoxExtensions.KeepSelectedItemVisible Attached Property 
} 

XAML:

<ListBox DockPanel.Dock="Top" 
     ItemsSource="{Binding Books, Mode=OneWay}" 
     SelectedItem="{Binding CurrentBook, Mode=TwoWay}" 
     SelectedIndex="{Binding SelectedIndex}" 
     local:ListBoxExtensions.KeepSelectedItemVisible="True" 
     /> 
+0

感谢您的快速回复,会看它的明天^^ –