我在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();
}
}
}
正确填充数据网格行:
我在viewmodel中收听属性更改事件。当我将其设置为处理程序然后更改数据网格的单元格时,会触发该事件并触发断点。
如果更改是实际更改,则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}"/>
但是将相同的Foreground绑定放到DataGridTextColumns
上并不起作用。我尝试调整此处的答案(Change Color of 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>
我发现的所有其他单元格颜色更改答案都是关于设置触发器,如果值更改为指定值,则可以更改颜色。
所以我决定选择&#34;真正改变是/否&#34;方法并添加了一个样式触发我的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%了解触发器的工作原理,以及它是否真的知道该怎么做......
由于
答案 0 :(得分:0)
如果我清楚地了解您想要标记用户当前编辑的单元格。因此,如果您使用的是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您应该添加到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}" />
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;
}