我已经实现类似于此帖子使用一个ViewModel存储IsSelected值,并且由ListViewItem.IsSelected结合视图模型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”,所有的项目都被选择,但是对于非可见项,视图模型没有得到它的IsSelected设置为true。即逻辑的,因为如果不创建ListViewItem,结合不能工作。

任何人(从没有使用VirtualizingStackPanel开)经历了同样的问题,并发现了一个解决方案?

有帮助吗?

解决方案

我发现在MVVM模式,它解决了我的问题的处理选择另一种方式。相反,保持在视图模型的选择,选择从ListView控件/列表框检索,并将其作为参数的命令通过。在所有XAML完成:

<ListView 
    x:Name="_items"
    ItemsSource="{Binding Items}" ... />

<Button 
    Content="Remove Selected" 
    Command="{Binding RemoveSelectedItemsCommand}" 
    CommandParameter="{Binding ElementName=_items, Path=SelectedItems}"/>

在我的视图模型:

private void RemoveSelection(object parameter)
{
    IList selection = (IList)parameter;
    ...
}

其他提示

在我的情况下,我结束了通过导出从列表框一个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;
        }
    }
}

除了不使用VirtualizingStackPanel,我能想到的唯一的事情就是要捕捉那些键盘快捷键和有让自己ViewModel属性设置为IsSelected修改一定范围内的True项目的方法(例如,SelectAll()SelectFromCurrentToEnd()) 。基本上绕过上BindingListViewItem用于控制这种情况下的选择。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top