我实现了一个类似于this post中描述的选择模式,使用ViewModel存储IsSelected值,并将ListViewItem.IsSelected绑定到ViewModel IsSelected:
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListView.ItemContainerStyle>一般来说,它是有效的,但我遇到了一个严重的问题。通过使用VirtualizingStackPanel作为列表视图中的面板,只创建可见的ListViewItem。如果我使用"Ctrl+A“来选择所有的项目,或者在第一个项目上使用快捷方式组合,比如"Shift+Ctrl+End”,所有的项目都会被选中,但对于不可见的项目,ViewModel不会将其IsSelected设置为true。这是合乎逻辑的,因为如果不创建ListViewItem,绑定就不能工作。
有没有人遇到过同样的问题,并找到了解决方案(除了不使用VirtualizingStackPanel)?
发布于 2009-08-13 19:43:48
我找到了在MVVM模式中处理选择的另一种方法,它解决了我的问题。不是在视图模型中维护选择,而是从ListView/ListBox中检索选择,并将其作为参数传递给Command。所有操作都在XAML中完成:
<ListView
x:Name="_items"
ItemsSource="{Binding Items}" ... />
<Button
Content="Remove Selected"
Command="{Binding RemoveSelectedItemsCommand}"
CommandParameter="{Binding ElementName=_items, Path=SelectedItems}"/>在我的ViewModel中:
private void RemoveSelection(object parameter)
{
IList selection = (IList)parameter;
...
}发布于 2009-11-12 23:50:59
在我的例子中,我最终解决了这个问题,方法是从ListBox派生一个ListBoxEx类,并添加代码来响应选择更改,在项目视图模型上强制执行选择状态:
private readonly List<IListItemViewModelBase> selectedItems = new List<IListItemViewModelBase>();
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
bool isVirtualizing = VirtualizingStackPanel.GetIsVirtualizing(this);
bool isMultiSelect = (SelectionMode != SelectionMode.Single);
if (isVirtualizing && isMultiSelect)
{
var newSelectedItems = SelectedItems.Cast<IListItemViewModelBase>();
foreach (var deselectedItem in this.selectedItems.Except(newSelectedItems))
{
deselectedItem.IsSelected = false;
}
this.selectedItems.Clear();
this.selectedItems.AddRange(newSelectedItems);
foreach (var newlySelectedItem in this.selectedItems)
{
newlySelectedItem.IsSelected = true;
}
}
}发布于 2009-08-13 19:08:14
除了不使用VirtualizingStackPanel之外,我唯一能想到的就是捕获这些键盘快捷键,并使用一些方法来修改某个范围内的ViewModel项,以便将它们的IsSelected属性设置为True (例如,SelectAll()、SelectFromCurrentToEnd())。基本上绕过ListViewItem上的Binding来控制此类情况下的选择。
https://stackoverflow.com/questions/1273659
复制相似问题