Nel*_*eis 2 c# wpf listbox observablecollection mvvm
我正在尝试在WPF中实现MVVM模式.我已经关注了Jeremy Alles的非常简单的MVVM演示应用程序.我有一个ListBox,它绑定到ObservableCollection:
<ListBox
Name="myListBox"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Persons}">
<ListBox.ItemTemplate>
<DataTemplate>
<views:PersonsView />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
我添加了一个ICollectionView来管理ListBox上的选定项目.它还允许我有两个按钮,允许我选择列表中的上一个和下一个项目.
private void GoToPrevious()
{
this.collectionView.MoveCurrentToPrevious();
}
private void GoToNext()
{
this.collectionView.MoveCurrentToNext();
}
Run Code Online (Sandbox Code Playgroud)
这一切都很有效,但是,当所选项目低于列表框的显示区域时,列表框的滚动条不会相应移动.
如何将ListBox的滚动条/显示区域与所选项目同步?
我找到了答案.我需要使用
myListBoxItem.BringIntoView();
Run Code Online (Sandbox Code Playgroud)
问题是我不想添加任何代码隐藏,因为我正在实现MVVM.
解决方案是使用附加行为.Josh Smith有一篇很棒的文章:WPF中的附加行为简介.
我在SetBox中找到了ListBox中项目的样式:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter
Property="custom:ListBoxItemBehavior.IsBroughtIntoViewWhenSelected"
Value="True" />
</Style>
</ListBox.ItemContainerStyle>
Run Code Online (Sandbox Code Playgroud)
并添加了以下类(仅将Josh的文章中的TreeView更改为ListBox):
public static class ListBoxItemBehavior
{
#region IsBroughtIntoViewWhenSelected
public static bool GetIsBroughtIntoViewWhenSelected(ListBoxItem listBoxItem)
{
return (bool)listBoxItem.GetValue(IsBroughtIntoViewWhenSelectedProperty);
}
public static void SetIsBroughtIntoViewWhenSelected(
ListBoxItem listBoxItem, bool value)
{
listBoxItem.SetValue(IsBroughtIntoViewWhenSelectedProperty, value);
}
public static readonly DependencyProperty IsBroughtIntoViewWhenSelectedProperty =
DependencyProperty.RegisterAttached(
"IsBroughtIntoViewWhenSelected",
typeof(bool),
typeof(ListBoxItemBehavior),
new UIPropertyMetadata(false, OnIsBroughtIntoViewWhenSelectedChanged));
static void OnIsBroughtIntoViewWhenSelectedChanged(
DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
ListBoxItem item = depObj as ListBoxItem;
if (item == null)
return;
if (e.NewValue is bool == false)
return;
if ((bool)e.NewValue)
item.Selected += OnListBoxItemSelected;
else
item.Selected -= OnListBoxItemSelected;
}
static void OnListBoxItemSelected(object sender, RoutedEventArgs e)
{
// Only react to the Selected event raised by the ListBoxItem
// whose IsSelected property was modified. Ignore all ancestors
// who are merely reporting that a descendant's Selected fired.
if (!Object.ReferenceEquals(sender, e.OriginalSource))
return;
ListBoxItem item = e.OriginalSource as ListBoxItem;
if (item != null)
item.BringIntoView();
}
#endregion // IsBroughtIntoViewWhenSelected
}
Run Code Online (Sandbox Code Playgroud)
有用!!
| 归档时间: |
|
| 查看次数: |
4115 次 |
| 最近记录: |