WINUI 3 Community Toolkit DataGrid能否按行设置IsReadOnly?
WinUI3 Community Toolkit DataGrid 实现单行可编辑(整体只读,点击按钮激活选中行编辑)
这个需求完全可行,核心思路是通过绑定每行的可编辑状态,结合DataGrid的属性或事件控制编辑权限,具体实现步骤如下:
1. 准备数据实体类
给你的数据实体添加IsRowEditable布尔属性,用来标记当前行是否允许编辑,需实现INotifyPropertyChanged通知UI更新:
public class YourDataItem : INotifyPropertyChanged { // 原有业务属性示例 public string Name { get; set; } public int Age { get; set; } private bool _isRowEditable; public bool IsRowEditable { get => _isRowEditable; set { _isRowEditable = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 配置DataGrid的XAML
- 先将DataGrid的
IsReadOnly设为True,确保整体默认只读 - 给需要编辑的列,将
IsReadOnly绑定到实体IsRowEditable的反值(因为IsReadOnly=True时不可编辑,所以当IsRowEditable=True时,列需设为可编辑) - 绑定DataGrid的
SelectedItem到ViewModel的选中项,方便后续修改状态
示例XAML:
<Page.Resources> <local:BooleanNegationConverter x:Key="BooleanNegationConverter"/> </Page.Resources> <controls:DataGrid x:Name="YourDataGrid" IsReadOnly="True" ItemsSource="{Binding YourDataList}" SelectedItem="{Binding SelectedDataItem}"> <controls:DataGrid.Columns> <controls:DataGridTextColumn Header="姓名" Binding="{Binding Name}" IsReadOnly="{Binding IsRowEditable, Converter={StaticResource BooleanNegationConverter}}"/> <controls:DataGridTextColumn Header="年龄" Binding="{Binding Age}" IsReadOnly="{Binding IsRowEditable, Converter={StaticResource BooleanNegationConverter}}"/> <!-- 其他列按此逻辑配置 --> </controls:DataGrid.Columns> </controls:DataGrid> <!-- 编辑按钮 --> <Button Content="编辑选中行" Command="{Binding EditSelectedRowCommand}"/>
其中BooleanNegationConverter是布尔取反转换器,实现代码如下:
public class BooleanNegationConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { return !(bool)value; } public object ConvertBack(object value, Type targetType, object parameter, string language) { return !(bool)value; } }
3. ViewModel中实现编辑逻辑
在ViewModel里处理编辑按钮命令,将选中行的IsRowEditable设为True,并触发DataGrid进入编辑状态:
public class YourViewModel : INotifyPropertyChanged { public ObservableCollection<YourDataItem> YourDataList { get; set; } = new ObservableCollection<YourDataItem>(); private YourDataItem _selectedDataItem; public YourDataItem SelectedDataItem { get => _selectedDataItem; set { _selectedDataItem = value; OnPropertyChanged(); } } public ICommand EditSelectedRowCommand => new RelayCommand(EditSelectedRow); private void EditSelectedRow() { if (SelectedDataItem == null) return; // 可选:将所有行设为不可编辑,确保仅选中行可编辑 foreach (var item in YourDataList) { item.IsRowEditable = false; } // 激活选中行的编辑状态 SelectedDataItem.IsRowEditable = true; // 触发DataGrid进入编辑模式,定位到选中行 YourDataGrid.DispatcherQueue.TryEnqueue(() => { YourDataGrid.ScrollIntoView(SelectedDataItem); YourDataGrid.BeginEdit(); }); } // INotifyPropertyChanged实现 public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
4. 替代方案:通过事件控制编辑
如果不想用列绑定,也可以通过DataGrid的BeginningEdit事件控制编辑权限:
private void YourDataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) { var item = e.Row.DataContext as YourDataItem; if (item != null && !item.IsRowEditable) { e.Cancel = true; } }
内容的提问来源于stack exchange,提问作者CloudFrugality
相关产品推荐
相关产品推荐

