【发布时间】:2023-03-15 07:00:01
【问题描述】:
在扩展选择模式下IsSelected 绑定似乎有问题。看起来只有选择中的最后一项超出范围得到了正确处理。
演示:
项目0、1、2 和98、97、96 使用Control 选择。选择94(没有 Control KBD>!)选择计数器应该是1,但你看到3。向上滚动显示只有一个(最后一个)超出范围的选择项未被选中。
下面是mcve:
xaml:
<ListBox ItemsSource="{Binding Items}" SelectionMode="Extended" SelectionChanged="ListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Text}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
cs:
public class NotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string property = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
public class Item : NotifyPropertyChanged
{
bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set { _isSelected = value; }
}
public string Text { get; set; }
}
public class ViewModel : NotifyPropertyChanged
{
public ObservableCollection<Item> Items { get; }
public ViewModel()
{
var list = new List<Item>();
for (int i = 0; i < 100; i++)
list.Add(new Item() { Text = i.ToString() });
Items = new ObservableCollection<Item>(list);
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Title = ((ViewModel)DataContext).Items.Count(item => item.IsSelected).ToString();
}
}
快速解决方法是禁用列表控制(ListBox 或 ListView)虚拟化:
VirtualizingStackPanel.IsVirtualizing="False"
问题:知道如何在不禁用虚拟化的情况下修复它吗?
【问题讨论】:
-
我怀疑项目的“选定”方面是启用虚拟化时您需要自己做的事情。虚拟化(至少从原生 Windows 而言)只是为了提供关于应该显示哪些项目的提示,而不是为您显示它。它与滚动条一起工作。这允许您的应用显示 1000 多个项目。可见的项目数通常保持不变(最后一页或项目数少于屏幕正常显示的项目数除外)。
-
在我看来可视化模式设置为回收,所以它会重复使用选定的项目,您是否尝试过更改虚拟化模式,例如:
VirtualizingPanel.VirtualizationMode="Standard"? -
@XAMlMAX,你可以复制mcve自己试试,说不定会找到解决办法。
VirtualizingMode="Standard"没有任何改进(尝试使用VirtualizingPanel和VirtualizingStackPanel)。
标签: c# wpf mvvm selection virtualization