C# 当绑定属性的值更改时更改DataGrid单元格的文本颜色

C# 当绑定属性的值更改时更改DataGrid单元格的文本颜色,c#,wpf,xaml,mvvm,datagrid,C#,Wpf,Xaml,Mvvm,Datagrid,我在WPF中有一个DataGrid,其中填充了observedcollection(ElementGroup具有ID和Text属性并从XML文件读取的项)。 我想要实现的是,当用户编辑单元格的值时,单元格内容的文本颜色会发生变化。一旦用户离开单元格,单元格的颜色应保持为绿色,并且该值与原始值不同 到目前为止,我所拥有的: 具有以下datagrid的用户控件: <DataGrid Grid.Row="7" Grid.Column="3" ItemsSource="{Binding Confi

我在WPF中有一个
DataGrid
,其中填充了
observedcollection
ElementGroup
具有ID和Text属性并从XML文件读取的项)。 我想要实现的是,当用户编辑单元格的值时,单元格内容的文本颜色会发生变化。一旦用户离开单元格,单元格的颜色应保持为绿色,并且该值与原始值不同

到目前为止,我所拥有的:

具有以下datagrid的用户控件:

<DataGrid Grid.Row="7" Grid.Column="3" ItemsSource="{Binding Config.ElementGroups, Mode=TwoWay}" AutoGenerateColumns="False" >            
    <DataGrid.Columns>  
        <DataGridTextColumn Header="ID" Binding="{Binding Id, Mode=TwoWay}" Width="Auto"/>
        <DataGridTextColumn Header="Group Name" Binding="{Binding Text, Mode=TwoWay}" Width="*" />
    </DataGrid.Columns>
</DataGrid>
<DataGrid Grid.Row="7" Grid.Column="3" ItemsSource="{Binding Config.ElementGroups, Mode=TwoWay}" AutoGenerateColumns="False" >
    <DataGrid.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding GroupChanged}" Value="True">
                    <Setter Property="Background" Value="Green"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding GroupChanged}" Value="False">
                    <Setter Property="Background" Value="Black"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.CellStyle>
    <DataGrid.Columns>  
        <DataGridTextColumn Header="ID" Binding="{Binding Id, Mode=TwoWay}" Width="Auto"/>
        <DataGridTextColumn Header="Group Name" Binding="{Binding Text, Mode=TwoWay}" Width="*" />
    </DataGrid.Columns>
</DataGrid>
数据网格行已正确填充:

我在viewmodel中侦听属性更改事件。当我将事件设置为处理程序,然后更改datagrid的一个单元格时,会触发该事件并命中断点。 如果更改为真实更改,则
HasTextChanged
HasIdChanged
函数返回true;如果值更改为以前的值,则返回false

private void GroupPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
    ElementGroup changedGroup = sender as ElementGroup;

    switch (propertyChangedEventArgs.PropertyName)
    {
        case "Text":
            GroupChanged = HasTextChanged(changedGroup);
            OnPropertyChanged("GroupChanged");
            break;
        case "Id":
            GroupChanged = HasIdChanged(changedGroup);
            OnPropertyChanged("GroupChanged");
            break;
    }           
}
我所尝试的:

起初我认为我只是返回一种颜色并将前景颜色绑定到datagrid,就像它处理一个简单的
文本框一样:

<TextBox Grid.Row="5" Grid.Column="3" Text="{Binding Config.Description}" Foreground="{Binding DescriptionColor}"/>
我找到的所有其他单元格颜色更改答案都是关于设置触发器的,如果值更改为指定值,则可以更改颜色

因此,我决定采用“真正的更改是/否”的方法,并添加了一个样式触发器my datagrid:

<DataGrid Grid.Row="7" Grid.Column="3" ItemsSource="{Binding Config.ElementGroups, Mode=TwoWay}" AutoGenerateColumns="False" >            
    <DataGrid.Columns>  
        <DataGridTextColumn Header="ID" Binding="{Binding Id, Mode=TwoWay}" Width="Auto"/>
        <DataGridTextColumn Header="Group Name" Binding="{Binding Text, Mode=TwoWay}" Width="*" />
    </DataGrid.Columns>
</DataGrid>
<DataGrid Grid.Row="7" Grid.Column="3" ItemsSource="{Binding Config.ElementGroups, Mode=TwoWay}" AutoGenerateColumns="False" >
    <DataGrid.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding GroupChanged}" Value="True">
                    <Setter Property="Background" Value="Green"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding GroupChanged}" Value="False">
                    <Setter Property="Background" Value="Black"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.CellStyle>
    <DataGrid.Columns>  
        <DataGridTextColumn Header="ID" Binding="{Binding Id, Mode=TwoWay}" Width="Auto"/>
        <DataGridTextColumn Header="Group Name" Binding="{Binding Text, Mode=TwoWay}" Width="*" />
    </DataGrid.Columns>
</DataGrid>

这也不起作用,我开始怀疑我是否错过了一些基本的东西

有没有人知道我做错了什么,或者我必须做什么才能让它正常工作? 我必须承认,我不是100%了解触发器是如何工作的,如果它真的知道该怎么做


如果我清楚地了解到您想要标记用户当前编辑的单元格,请多谢。因此,如果您使用的是
DataGridTextBoxColumns
,则可以为它们添加
EditingElementStyle

<DataGrid.Resources>
    <Style x:Key="EditingStyle" TargetType="TextBox">
        <Setter Property="Background" Value="Green" />
        <Setter Property="Foreground" Value="White" />
    </Style>
</DataGrid.Resources>
2您应该将添加到id设置器中
IsIdChanged=true

...
myId = value;
OnPropertyChanged();
IsIdChanged = true;
3更改
ID
列的绑定

Binding="{Binding Id, Mode=TwoWay, NotifyOnTargetUpdated=True}"
4为该列添加样式

<Style x:Key="IdStyle" TargetType="DataGridCell">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsIdChanged}" Value="True">
            <Setter Property="Background" Value="Green" />
        </DataTrigger>
    </Style.Triggers>
</Style>

<DataGridTextColumn Name="ID" ... CellStyle="{StaticResource IdStyle}" />
您应该将这些字符串添加到
changeconfigsetingviewmodel
的构造函数中。它应该是初始化
IdChanged
值为false的构造函数的最后一个字符串

foreach ( PersonModel pers in myPersons )
{
    pers.IdChanged = false;
}

如果我清楚地了解您想要标记用户当前编辑的单元格。因此,如果您使用的是
DataGridTextBoxColumns
,则可以为它们添加
EditingElementStyle

<DataGrid.Resources>
    <Style x:Key="EditingStyle" TargetType="TextBox">
        <Setter Property="Background" Value="Green" />
        <Setter Property="Foreground" Value="White" />
    </Style>
</DataGrid.Resources>
2您应该将添加到id设置器中
IsIdChanged=true

...
myId = value;
OnPropertyChanged();
IsIdChanged = true;
3更改
ID
列的绑定

Binding="{Binding Id, Mode=TwoWay, NotifyOnTargetUpdated=True}"
4为该列添加样式

<Style x:Key="IdStyle" TargetType="DataGridCell">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsIdChanged}" Value="True">
            <Setter Property="Background" Value="Green" />
        </DataTrigger>
    </Style.Triggers>
</Style>

<DataGridTextColumn Name="ID" ... CellStyle="{StaticResource IdStyle}" />
您应该将这些字符串添加到
changeconfigsetingviewmodel
的构造函数中。它应该是初始化
IdChanged
值为false的构造函数的最后一个字符串

foreach ( PersonModel pers in myPersons )
{
    pers.IdChanged = false;
}

很有趣,但这不是我想要实现的。也许我不够清楚。我不想在编辑过程中更改颜色,但是当值被编辑并且用户单击其他位置时,颜色应该保持不变。谢谢您的努力。不幸的是,这对我也不起作用。我看到属性已更改,值设置为“true”,但颜色不会更改。。。就好像信息没有进入数据网格一样。也许我的代码有一些基本的错误。。。如果我只有这个datagrid,我想我会创建一个新项目,看看它是否有效。您可以将
Style
中的
DataTrigger
更改为
Binding={Binding Id}Value=“5”
并将
datagrid
中的Id更改为5,以测试向列添加样式的正确性。在我的测试示例中,它工作正常,可能在
OnPropertyChanged()
函数中存在一些问题。没有颜色变化。我已经更改了
ElementGroup
项的
PropertyChanged
事件的事件处理程序,以便在消息框中显示更改属性的名称:我在编辑datagrid单元格时获得Id或文本更改的正确信息。但是我没有得到新的
IsIdChanged
属性的消息框。不幸的是,绑定id并将数字设置为值也不起作用:(我不知道,但我肯定遗漏了一些基本的东西……你能为你的代码提供这些更新吗?也许我会看到一些我们遗漏的东西。有趣的是,但这不是我想要实现的。也许我不够清楚。我不想在编辑过程中更改颜色,但当值被编辑并且用户单击某个位置时e、 颜色应该保持不变。感谢您的努力。不幸的是,这对我也不起作用。我看到属性已更改,并且值设置为“true”,但颜色不会改变…就像信息没有进入数据网格一样。可能我的代码有一些基本错误…我想我会创建一个新项目,看看如果我只有这个数据网格,它是否有效。你可以将
样式中的
DataTrigger
更改为
Binding={Binding Id}Value=“5”
并在
DataGrid
中将id更改为5,只是为了测试向列添加样式的正确性。在我的测试示例中,它工作正常,可能在
OnPropertyChanged()中存在一些问题
函数。我已经尝试过了,但仍然没有改变颜色。我已经更改了
ElementGroup
项的
PropertyChanged
事件的事件处理程序,只在消息框中显示更改属性的名称:我在编辑datagrid单元格时获得了Id或文本更改的正确信息。但我没有得到消息框对于新的
IsIdChanged
属性。不幸的是,绑定id并将数字设置为值无法正常工作