K J*_*K J 4 c# wpf listview filter mvvm
我在VM中有一个ObservableCollection,它显示在ListView的视图中.当所选项更改时,SelectionChanged事件将很好地触发.以下是我配置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>
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是当我更改集合上的过滤器时.所选项目保持不变,这很好,但ListView会更改为从第一个项目显示,并且通常所选项目不在视图范围内(但仍然是所选项目).
在VM中,我有属性"SelectedSettingIndex",它在更改时抛出PropertyChanged事件.即使我提出了自己的事件手动(base.OnPropertyChanged("SelectedSettingIndex");)从虚拟机时更换过滤器,似乎事件不会真正引起人们的关注与物业并没有真正改变.必须有一个方法来调用ScrollIntoView或在这种情况下类似的东西,但我无法找出正确的事件或者触发这样做.我错过了什么?
编辑
以下是我关注的问题的一个,希望更好的描述:
1)我在VM中使用CollectionViewSource来过滤数据.
2)有一个按钮供用户在过滤器之间切换.
3)让我们假设ListView有空间在任何给定时间显示最多10个项目.
4)用户在列表视图中的索引50处的过滤视图中选择项"A".
5)然后用户单击该按钮以关闭过滤.
预期结果:ListView控件填充了未经过滤的名单,项目"A"保持选中状态,并且ListView的是"滚动",使得项目"A"仍是可见的.
实际结果:ListView中填充了未过滤的列表中,项"A"保持被选择,并且所述的ListView为"滚动"到顶部,示出第一10项.项目"A"不在视野中.
Ank*_*esh 12
如果你正在使用MVVM,那么你需要确保你已经设置了绑定到viewModel中的选定项目,并且那也是Mode=TwoWay...和滚动选择我们必须使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
将别名添加到XAMLas xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
然后在你的Control
DisplayMemberBinding ="{Binding Path = Setting}"/>中
现在,当ViewModel重新选择更改时,将在列表中设置"MySelectedItem"属性时滚动.
在viewModel中应调用已绑定到xaml的属性setter中更改的INotifyProperty,以便viewModel中的更改可以重新选择到View ...
同样在MVVM中,您必须使用"SelectionChnaged Event",因为您可以在Setter of MySelectedItem属性中调用函数,或者您可以使用EventToCommandclass进行显式事件调用.
Google使用ColletionViewSource进行排序,过滤等功能
希望能帮助到你...
| 归档时间: |
|
| 查看次数: |
3490 次 |
| 最近记录: |