首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VirtualizingStackPanel + MVVM +多选

VirtualizingStackPanel + MVVM +多选
EN

Stack Overflow用户
提问于 2009-08-13 18:07:56
回答 3查看 13.6K关注 0票数 28

我实现了一个类似于this post中描述的选择模式,使用ViewModel存储IsSelected值,并将ListViewItem.IsSelected绑定到ViewModel IsSelected:

代码语言:javascript
复制
<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)?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-08-13 19:43:48

我找到了在MVVM模式中处理选择的另一种方法,它解决了我的问题。不是在视图模型中维护选择,而是从ListView/ListBox中检索选择,并将其作为参数传递给Command。所有操作都在XAML中完成:

代码语言:javascript
复制
<ListView 
    x:Name="_items"
    ItemsSource="{Binding Items}" ... />

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

在我的ViewModel中:

代码语言:javascript
复制
private void RemoveSelection(object parameter)
{
    IList selection = (IList)parameter;
    ...
}
票数 32
EN

Stack Overflow用户

发布于 2009-11-12 23:50:59

在我的例子中,我最终解决了这个问题,方法是从ListBox派生一个ListBoxEx类,并添加代码来响应选择更改,在项目视图模型上强制执行选择状态:

代码语言:javascript
复制
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;
        }
    }
}
票数 6
EN

Stack Overflow用户

发布于 2009-08-13 19:08:14

除了不使用VirtualizingStackPanel之外,我唯一能想到的就是捕获这些键盘快捷键,并使用一些方法来修改某个范围内的ViewModel项,以便将它们的IsSelected属性设置为True (例如,SelectAll()SelectFromCurrentToEnd())。基本上绕过ListViewItem上的Binding来控制此类情况下的选择。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1273659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档