WPF MVVM中DataGrid单元格值变更后前景色设置失效问题求助
WPF DataGrid单元格修改后前景色提示及保存激活方案
需求
当WPF DataGrid的单元格值变更时,将单元格前景色设为蓝色,以此提示用户值已修改,同时激活保存功能。
最初尝试(未生效)
- 在
MainVM类中创建布尔属性CellInEdit,计划在单元格值变更时将其设为True - 实现
BoolenToGridForegroundConverter类,完成布尔值到前景色的转换逻辑 - 绑定后发现该方案完全不生效,无法实现预期的前景色变化
相关代码示例
XAML代码
<!-- 示例DataGrid绑定代码 --> <DataGrid ItemsSource="{Binding Persons}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="Name" Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}"> <DataGridTextColumn.CellStyle> <Style TargetType="DataGridCell"> <Setter Property="Foreground" Value="{Binding DataContext.CellInEdit, RelativeSource={RelativeSource AncestorType=Window}, Converter={StaticResource BoolToForegroundConverter}}"/> </Style> </DataGridTextColumn.CellStyle> </DataGridTextColumn> <!-- 其他列省略 --> </DataGrid.Columns> </DataGrid>
Person模型类
public class Person : INotifyPropertyChanged { private string _name; public string Name { get => _name; set { _name = value; OnPropertyChanged(nameof(Name)); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
MainVM类
public class MainVM : INotifyPropertyChanged { private bool _cellInEdit; public bool CellInEdit { get => _cellInEdit; set { _cellInEdit = value; OnPropertyChanged(nameof(CellInEdit)); // 激活保存功能的逻辑 } } public ObservableCollection<Person> Persons { get; set; } public MainVM() { Persons = new ObservableCollection<Person>(); // 初始化数据逻辑 } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
IValueConverter实现类
public class BoolenToGridForegroundConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is bool isEdited && isEdited) { return Brushes.Blue; } return Brushes.Black; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
解决方法
将CellInEdit布尔属性从MainVM类移至Person模型类中,同时在Person的属性 setter 中触发CellInEdit的变更通知,修改后的Person类如下:
public class Person : INotifyPropertyChanged { private string _name; public string Name { get => _name; set { _name = value; OnPropertyChanged(nameof(Name)); CellInEdit = true; // 修改时标记为已编辑 } } private bool _cellInEdit; public bool CellInEdit { get => _cellInEdit; set { _cellInEdit = value; OnPropertyChanged(nameof(CellInEdit)); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
同时调整XAML中的绑定路径,去掉RelativeSource,直接绑定到当前行的DataContext:
<Setter Property="Foreground" Value="{Binding CellInEdit, Converter={StaticResource BoolToForegroundConverter}}"/>
调整完成后,单元格值修改时前景色会变为蓝色,同时可以通过CellInEdit属性的变化触发保存功能的激活逻辑,问题完美解决。
内容的提问来源于stack exchange,提问作者Gokhan
相关产品推荐
相关产品推荐

