WinUI 3+C#:如何绑定ListView多选自动生成的CheckBox?
WinUI 3 ListView 多选复选框绑定自定义IsSelected属性
当WinUI 3的ListView设置SelectionMode="Multiple"时,自动生成的复选框属于ListViewItem内部控件,无法直接绑定自定义数据对象的IsSelected属性,下面提供两种可行的实现方式:
方案一:通过修改ListViewItem样式实现绑定
自定义ListViewItem的模板,将自动生成的复选框状态与数据项的IsSelected属性双向绑定:
- 在页面资源中定义自定义ListViewItem样式:
<Page.Resources> <Style x:Key="CustomListViewItemStyle" TargetType="ListViewItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListViewItem"> <ListViewItemPresenter CheckBoxBrush="{ThemeResource SystemControlForegroundBaseHighBrush}" ContentMargin="{TemplateBinding Padding}" <!-- 核心绑定:将复选框状态与数据项IsSelected双向绑定 --> CheckBoxIsChecked="{Binding IsSelected, Mode=TwoWay}" ContentTransitions="{TemplateBinding ContentTransitions}" CheckMode="Inline" DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}" DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}" DragBackground="{ThemeResource ListViewItemDragBackground}" DragForeground="{ThemeResource ListViewItemDragForeground}" FocusBorderBrush="{ThemeResource SystemControlForegroundAltHighBrush}" FocusSecondaryBorderBrush="{ThemeResource SystemControlForegroundBaseHighBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" PointerOverBackground="{ThemeResource ListViewItemPointerOverBackground}" PointerOverForeground="{ThemeResource ListViewItemPointerOverForeground}" PressedBackground="{ThemeResource ListViewItemPressedBackground}" ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" SelectedBackground="{ThemeResource ListViewItemSelectedBackground}" SelectedForeground="{ThemeResource ListViewItemSelectedForeground}" SelectedPointerOverBackground="{ThemeResource ListViewItemSelectedPointerOverBackground}" SelectedPressedBackground="{ThemeResource ListViewItemSelectedPressedBackground}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/> </ControlTemplate> </Setter.Value> </Setter> </Style> </Page.Resources>
- 修改ListView的
ItemContainerStyle引用自定义样式:
<ListView x:Name="filterListView" SelectionMode="Multiple" ItemContainerStyle="{StaticResource CustomListViewItemStyle}"> <ListView.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding SubFilterName}" TextWrapping="Wrap" /> </DataTemplate> </ListView.ItemTemplate> </ListView>
方案二:通过C#后台事件同步选中状态
如果不想修改样式,可以通过监听ListView的选择事件和数据项的属性变化事件,实现双向状态同步:
- 确保数据项实现
INotifyPropertyChanged接口:
public class SubFilter : INotifyPropertyChanged { private string _subFilterName; private bool _isSelected; public string SubFilterName { get => _subFilterName; set { _subFilterName = value; OnPropertyChanged(nameof(SubFilterName)); } } public bool IsSelected { get => _isSelected; set { _isSelected = value; OnPropertyChanged(nameof(IsSelected)); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
- 后台代码绑定事件并同步状态:
public MainPage() { InitializeComponent(); // 初始化示例数据 var subFilters = new ObservableCollection<SubFilter> { new SubFilter { SubFilterName = "筛选项1", IsSelected = false }, new SubFilter { SubFilterName = "筛选项2", IsSelected = true }, new SubFilter { SubFilterName = "筛选项3", IsSelected = false } }; filterListView.ItemsSource = subFilters; // 监听ListView选择变化,同步到数据项IsSelected filterListView.SelectionChanged += FilterListView_SelectionChanged; // 监听数据项属性变化,同步到ListView选中状态 foreach (var item in subFilters) { item.PropertyChanged += SubFilter_PropertyChanged; } } private void FilterListView_SelectionChanged(object sender, SelectionChangedEventArgs e) { foreach (SubFilter addedItem in e.AddedItems) { if (addedItem.IsSelected != true) addedItem.IsSelected = true; } foreach (SubFilter removedItem in e.RemovedItems) { if (removedItem.IsSelected != false) removedItem.IsSelected = false; } } private void SubFilter_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName != nameof(SubFilter.IsSelected)) return; var item = sender as SubFilter; if (item == null) return; if (item.IsSelected && !filterListView.SelectedItems.Contains(item)) { filterListView.SelectedItems.Add(item); } else if (!item.IsSelected && filterListView.SelectedItems.Contains(item)) { filterListView.SelectedItems.Remove(item); } }
内容的提问来源于stack exchange,提问作者Ethan Allen
相关产品推荐
相关产品推荐

