如何强制WinUI 3 DataGrid在绑定ItemsSource变更后重新渲染?
WinUI DataGrid复选框状态无法同步刷新问题解决
环境说明
- 使用CommunityToolkit.WinUI.UI.Controls.DataGrid控件
- ItemsSource绑定至ObservableCollection类型的对象集合
- 集合内对象包含绑定到复选框的布尔类型属性
Selected
问题现象
后台修改ObservableCollection中部分对象的Selected属性值后,DataGrid无法同步刷新复选框状态;但将受影响行滚动至不可见后再滚回,状态就能正常显示。不过这个临时方法在DataGrid行数不足无法滚动时不适用。
相关代码
DataGrid声明
<controls:DataGrid Grid.Row="1" AutoGenerateColumns="False" ItemsSource="{Binding UiModel.Dictionary.Values}" CanUserReorderColumns="False" GridLinesVisibility="All" BorderBrush="LightGray" BorderThickness="1" PointerPressed="DataGrid_PointerPressed">
字典定义
IDictionary<string, ObservableCollection<MyClass<T>>>
该字典实现了ObservableDictionary
MyClass定义
using CommunityToolkit.Mvvm.ComponentModel; public class MyClass<T> : ObservableObject { public string Display { get; set; } public T Identifier { get; set; } private bool _selected; public bool Selected { get { return _selected; } set { _ = SetProperty(ref _selected, value); } } }
复选框绑定模板
<controls:DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox Style="{StaticResource CompactCheckbox}" IsChecked="{Binding Path=[0].Selected, Mode=TwoWay}" HorizontalAlignment="Center" MinWidth="0" /> </DataTemplate> </controls:DataGridTemplateColumn.CellTemplate>
无效尝试
- 为CheckBox绑定添加
UpdateSourceTrigger=PropertyChanged无效果 - 为DataGrid的ItemsSource绑定添加
Mode=TwoWay, UpdateSourceTrigger=PropertyChanged无效果
解决方案
1. 修正复选框绑定路径
你的CheckBox绑定使用了[0]路径,这是错误的——DataGrid每行的DataContext就是集合中的MyClass<T>对象,直接绑定Selected属性即可:
<CheckBox Style="{StaticResource CompactCheckbox}" IsChecked="{Binding Selected, Mode=TwoWay}" HorizontalAlignment="Center" MinWidth="0" />
2. 强制DataGrid刷新
如果绑定路径无误,修改完Selected属性后手动触发DataGrid刷新界面:
// 替换为你的DataGrid实例名称 dataGrid.InvalidateArrange(); // 或使用UpdateLayout dataGrid.UpdateLayout();
3. 调整ItemsSource绑定方式
ObservableDictionary的Values集合可能无法正确通知UI更新。可以在ViewModel中封装一个直接指向目标ObservableCollection的属性:
// 示例:取字典首个值,可根据业务逻辑调整 public ObservableCollection<MyClass<T>> TargetItems => UiModel.Dictionary.Values.FirstOrDefault();
然后将DataGrid的ItemsSource绑定到该属性:
ItemsSource="{Binding TargetItems}"
4. 确保在UI线程修改属性
如果是后台线程修改Selected属性,必须切换到UI线程执行:
await DispatcherQueue.EnqueueAsync(() => { // 在此处修改对象的Selected属性 });
内容的提问来源于stack exchange,提问作者Craig Cote
相关产品推荐
相关产品推荐

