我有一个ViewModel
具有IsSelected
属性,我将ListView.ItemContainerStyle
XAML绑定到我的视图模型中的IsSelected
属性。
我打开应用程序并使用很多项目填充视图模型集合(在我的ListView
中显示),比如大约2000.然后我通过 Ctrl-A选择列表中的所有内容。我的视图模型集合中的项目仅为IsSelected
中可见的项目设置了ListView
。如果我向下翻阅列表,IsSelected
将被设置为显示的任何项目。如果我翻阅所有项目,那么我的视图模型中的所有项目都将IsSelected
属性设置为true。
以下是我的XAML,用于将列表视图中的IsSelected
绑定到我的视图模型:
<ListView Margin="5" ItemsSource="{Binding FilteredComparisonList}" x:Name="comparisonListView">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Source filename" DisplayMemberBinding="{Binding ImageFile.BaseFilename}" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
当我选择IsSelected
中的所有项目时,为什么ListView
我的视图模型中的所有项目都设置为无效?
答案 0 :(得分:4)
MVVM方法是使用您自己的SelectAll命令覆盖Ctrl-A快捷方式(使用快捷键Ctrl-A创建SellectAll命令)。实现将在视图模型上设置IsSelected。
视图中的IsSelected属性需要与视图模型进行双向绑定,以便在视图中显示选中的项目。
我不认为关闭虚拟化是必要的。
希望这有帮助。
答案 1 :(得分:3)
由于ListView的内置虚拟化,这种情况正在发生。如果你不熟悉它,它的基本含义是物品在它们可见之前不会变成现实。您可以使用以下属性关闭ListView的虚拟化:
VirtualizingStackPanel.IsVirtualizing="False"
但请注意,这会对ListView的性能产生负面影响。对于2,000件物品,它不会很严重,但可能会很明显。
答案 2 :(得分:2)
ListBoxItem是虚拟化的,它们在生成之前不存在(当它们被带入视图时)。但是,底层ListView派生自ListBox,它具有SelectedItems属性。 SelectedItems是所有选定项目的列表,而不是所选ListBoxItems的列表。当ListBoxItem进入视图时,它的IsSelected属性是根据它的项目(它显示的项目)是否在SelectedItems集合中设置的。
这是您的视图模型的一个问题,特别是如果您需要启用虚拟化(您可能需要2000个左右的项目)。我会对“如何根据项目是否在ListBox的SelectedItems集合中绑定我的视图模型IsSelected属性?”这个问题的答案感兴趣。
答案可能涉及转换器
答案 3 :(得分:0)
我遇到了同样的问题,这最终帮助了我:
加入ListView
:
VirtualizingStackPanel.VirtualizationMode="Standard"
答案 4 :(得分:0)
我发布了我在其他论坛上发现的答案,因为它帮助我解决了这个问题。
我已经为我的ViewModel定义了一个可选的接口来实现
public interface ISelectable
{
bool IsSelected { get; set; }
}
然后在MyCustomListView中我完成了这个:
public class MyCustomListView : ListView
{
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
foreach (var item in e.AddedItems.OfType<ISelectable>())
item.IsSelected = true;
foreach (var item in e.RemovedItems.OfType<ISelectable>())
item.IsSelected = false;
base.OnSelectionChanged(e);
}
}
或者,您可以订阅ListView的SelectionChanged事件并使用上面相同的代码。