在更改选定索引||时显示列表框中的选定项目滚动列表框
问题描述:
我有一个列表框显示在其中的书籍。 SelectedIndex
和Currentindex
绑定到视图模型中的属性。 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>
击中Next
和Last
按钮改变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"
/>
感谢您的快速回复,会看它的明天^^ –