当绑定属性的值更改时,更改DataGrid单元格的文本颜色
本文关键字:DataGrid 更改 单元格 文本 颜色 属性 绑定 | 更新日期: 2023-09-27 18:29:51
我在WPF中有一个DataGrid
,其中填充了ObservableCollection
的元素(ElementGroup
项具有ID和Text属性,并且是从XML文件中读取的)。我想要实现的是,当用户编辑了单元格的值时,单元格内容的文本颜色会发生变化。一旦用户离开单元格,单元格的颜色应保持为绿色,并且该值与原始值不同。
到目前为止我所拥有的:
具有以下数据网格的用户控件:
<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>
用户控件的代码隐藏中没有任何内容。
具有2个属性的ElementGroup类,它还实现了INotifyPropertyChanged
(为了重用它而增加的类)
public class ElementGroup : NotifyPropertyChangedBase, ITag
{
private int myId;
private string myText;
public ElementGroup()
{
Elements = new List<Element>();
}
public List<Element> Elements { get; private set; }
public int Id
{
get { return myId; }
set
{
if (myId == value)
{
return;
}
myId = value;
OnPropertyChanged();
}
}
public string Text
{
get { return myText; }
set
{
if (myText == value)
{
return;
}
myText = value;
OnPropertyChanged();
}
}
}
数据网格行已正确填充:
数据网格示例
我在视图模型中收听属性更改事件。当我将事件设置为处理程序,然后更改数据网格的一个单元格时,就会触发事件并命中断点。如果更改为实际更改,则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;
}
}
我尝试过的:
起初,我认为我只是返回一个颜色并将前景颜色绑定到数据网格,就像它在简单的TextBox
:中一样
<TextBox Grid.Row="5" Grid.Column="3" Text="{Binding Config.Description}" Foreground="{Binding DescriptionColor}"/>
但将相同的前景绑定到DataGridTextColumns
上并没有起作用。我试图调整这里找到的答案(更改DatagridCell的颜色),但无法使其工作(以下示例中的DescriptionColor
是SolidColorBrush DescriptionColor = Brushes.Green
:
<DataGridTextColumn Header="Group Name" Binding="{Binding Text, Mode=TwoWay}" Width="*" >
<DataGridTextColumn.CellStyle>
<Style>
<Setter Property="Border.Background" Value="{Binding DescriptionColor}"/>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
我发现的所有其他单元格颜色更改答案都是关于设置触发器的,如果值更改为指定值,则可以更改颜色。
因此,我决定采用"真正的改变是/否"的方法,并添加了一个风格触发我的数据网格:
<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>
列应该是这样的。
<DataGridTextColumn Header="ID" Binding="{Binding Id, Mode=TwoWay}" Width="Auto"
EditingElementStyle="{StaticResource EditingStyle}" />
更新
要重新绘制编辑过的单元格的颜色,可以在ElementGroup
中添加一些表示编辑过的单元的bool道具。像这样的东西。
private bool _isIdChanged;
public bool IsIdChanged
{
get { return _isIdChanged; }
set { _isIdChanged = value; NotifyPropertyChanged( "IsIdChanged" ); }
}
2您应该将IsIdChanged = true
添加到id setter中。
...
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}" />
5绑定到DataGrid后,应将集合元素的IsIdChanged
的所有值更改为false。在从代码后面更改值之后,它需要将其设置为false。
6应为其他列添加相同的代码。希望这能有所帮助。
更新
我已经查看了您的代码,您应该将DataTrigger
绑定到此。
<DataTrigger Binding="{Binding IdChanged}" Value="True">
<Setter Property="Background" Value="Green" />
</DataTrigger>
您应该在ChangeConfigSettingViewModel
的构造函数中添加这些字符串。它应该是构造函数的最后一个字符串,用于将IdChanged
值初始化为false。
foreach ( PersonModel pers in myPersons )
{
pers.IdChanged = false;
}