背景
WPF+Prism,View和ViewModel,通过Binding来实现数据的更新和界面的刷新,我的需求是做一个表格,第一列为CheckBox,同时这一列的header也是CheckBox,勾选了header的CheckBox,可以实现所有行的CheckBox全选的功能
界面如下:
实现方法
xaml代码:
<DataGrid x:Name="dgRoundRobin" Grid.Row="2" Height="300" Margin="0,5,0,0" AutoGenerateColumns="False" BorderBrush="Black" BorderThickness="1" CanUserAddRows="{Binding DgRobinCanUserAddRows}" GridLinesVisibility="All" ItemsSource="{Binding DgRoundRobinItems}"> <DataGrid.Columns> <DataGridCheckBoxColumn Binding="{Binding IsChecked}"> <DataGridCheckBoxColumn.HeaderTemplate> <DataTemplate> <CheckBox Command="{Binding DataContext.CbRoundRobinAllCheckCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" /> </DataTemplate> </DataGridCheckBoxColumn.HeaderTemplate> </DataGridCheckBoxColumn> <DataGridTextColumn Width="150" Binding="{Binding MAC}" Header="MAC" /> <DataGridTextColumn Width="100" Binding="{Binding SendCount}" Header="发送次数" /> <DataGridTextColumn Width="100" Binding="{Binding RcvCount}" Header="接收次数" /> <DataGridTextColumn Width="100" Binding="{Binding SuccessRate}" Header="成功率" /> <DataGridTextColumn Width="100" Binding="{Binding Status}" Header="状态" /> </DataGrid.Columns> </DataGrid>
我感觉主要的难点就在xaml中的代码编写,这样的方法是创建了一个DataGridCheckBoxColumn
,然后修改了它的HeaderTemplate
,在其中进行了CheckBox的绑定,<CheckBox Command="{Binding DataContext.CbRoundRobinAllCheckCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
这一行是重点,我们用常规手段直接给header中的CheckBox绑定command是行不通的,因为WPF中没有DataGridCheckBoxColumn
映射它(DataGridCheckBoxColumn
不是控件,它没有父控件)
所以需要我们手动找到DataGrid元素,找到他身上的DataContext来绑定CbRoundRobinAllCheckCommand
。
ViewModel中的代码:
DataGrid的ItemSource绑定的DgRoundRobinItems
,这个的定义如下:
private ObservableCollection<DgRoundRobinDeviceInfo> _dgRoundRobinItems = new ObservableCollection<DgRoundRobinDeviceInfo>(); public ObservableCollection<DgRoundRobinDeviceInfo> DgRoundRobinItems { get { return _dgRoundRobinItems; } set { SetProperty(ref _dgRoundRobinItems, value); } }
ObservableCollection
实现了INotifyCollectionChanged
和INotifyPropertyChanged
,所以这个集合中的Item有新增
或者删除的话,它会自动的调用UI进行更新,特别方便,以前我总是用List声明一个集合,但是当集合中的元素有新增或删除的时候,都得手动重新刷新下集合才行。
但是我还有个需求,就是想当集合中的Item的某个属性有变化的时候,也可以自动的刷新UI界面,不需要我自己来处理,后来发现还真的可以,只需要将Item的Class继承BindableBase
(这是Prism提供的,Community.Mvvm.Toolkit应该是用的ObservableObject),这样子,就可以实现我的需求,代码如下:
public class DgRoundRobinDeviceInfo : BindableBase { private bool _isChecked = false; public bool IsChecked { get { return _isChecked; } set { SetProperty(ref _isChecked, value); } } public string MAC { get; set; } public int SendCount { get; set; } public int RcvCount { get; set; } public string SuccessRate { get; set; } public string Status { get; set; } }
可以看到,我在DgRoundRobinDeviceInfo
中的IsChecked
属性上面实现了自动更新。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?