You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:47:22