WPF DataGrid绑定外部属性设置列IsReadOnly不生效问题
绑定失效原因
DataGridColumn 系列类型(包括你用的DataGridCheckBoxColumn)不属于WPF可视化树的一部分,没有继承的DataContext,直接在这类对象的依赖属性上写绑定,无法定位到ViewModel层的数据源,所以联动不会生效。
可行实现方案
直接将原有DataGridCheckBoxColumn替换为DataGridTemplateColumn,在单元格模板中放置CheckBox控件,通过相对源绑定找到上层DataGrid的DataContext,即可实现和IsConfirmed属性的联动,效果和列只读完全一致。
- 首先实现一个简单的布尔反向转换器,用于匹配「IsConfirmed为true时控件不可编辑」的逻辑:
using System; using System.Globalization; using System.Windows.Data; public class InverseBoolConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value is bool flag ? !flag : false; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return value is bool flag ? !flag : false; } }
- 在XAML的窗口/用户控件资源节点中注册转换器,注意将
local替换为你项目中转换器所在命名空间对应的前缀:
<Window.Resources> <local:InverseBoolConverter x:Key="InverseBoolConverter"/> </Window.Resources>
- 将DataGrid中原有的「Omit For SPC?」列替换为以下代码:
<DataGridTemplateColumn Header="Omit For SPC?"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox IsChecked="{Binding isOutlier, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding DataContext.IsConfirmed, RelativeSource={RelativeSource AncestorType=DataGrid}, Converter={StaticResource InverseBoolConverter}}" HorizontalAlignment="Center"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>
实现逻辑说明
- 模板列内的CheckBox属于可视化树元素,可以通过
RelativeSource找到外层命名为theGrid的DataGrid,进而拿到绑定的ViewModel实例,访问IsConfirmed属性不会出现数据源找不到的问题 - 当
IsConfirmed值为true时,转换器返回false,CheckBox被禁用,用户无法修改勾选状态,和列只读效果完全一致;当IsConfirmed为false时,CheckBox可正常点击修改,双向绑定会自动同步值到isOutlier属性 - 原有其他列的逻辑不需要做任何改动,和外部的Confirmed复选框联动完全同步
内容的提问来源于stack exchange,提问作者Daniel Patanroi
相关产品推荐
相关产品推荐

