Reputation: 969
I use a DataGrid in WPF to display values. Now I want to have green and red rows. I tried it out with DataTrigger but nothing happends.
My XAML:
<DataGrid x:Name="dgAbos" ItemsSource="{Binding Source=AboList}" HorizontalAlignment="Stretch" Margin="10,30,10,10" VerticalAlignment="Stretch" Height="Auto" Width="Auto">
<DataGrid.Columns>
<DataGridTextColumn Header="ItemID" Binding="{Binding ItemID}" />
</DataGrid.Columns>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Active}" Value="false">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Active}" Value="true">
<Setter Property="Background" Value="Green"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
The Binding type is:
ObservableCollection<OPCItem> AboList = new ObservableCollection<OPCItem>();
And the Item to display is OPCItem:
class OPCItem
{
public String ItemID { get; set; }
public String Name { get; set; }
public String Value { get; set; }
public DateTime DateTime { get; set; }
public String Group { get; set; }
private Boolean _Active;
public String Active
{
get
{
return (_Active == true ? "Aktiv" : "Inaktiv");
}
set
{
_Active = Convert.ToBoolean(value);
}
}
}
How I fill the list:
AboList.Add(new OPCItem { ItemID = Item.ItemID, Group = GroupName, Active = "true" });
But the row doesnt change the color, why?
Upvotes: 1
Views: 2164
Reputation: 37060
This is a really bad idea:
private Boolean _Active;
public String Active
{
get
{
return (_Active == true ? "Aktiv" : "Inaktiv");
}
set
{
_Active = Convert.ToBoolean(value);
}
}
So you set Active to "true" or "false", and you get back "Aktiv" or "Inaktiv"? The natural result of that is you confuse yourself to the point where you write a trigger assuming that Active.get
will return "true" or "false" instead of "Activ" or "Inaktiv". You can fix the immediate problem by just fixing the DataTrigger.Value
attributes as Grx70 suggests, but it's better in the long run to fix the underlying issue and to avoid bad habits like this. Particularly if you intend to work in the field, you really don't want to be writing this kind of stuff. Active
looks like a simple property, but the behavior is nothing that anybody would ever expect, so anybody interacting with it will be taken by surprise, and then they'll have to read the code to figure out what it does. Think about it this way: When you see a property on a WPF control called IsEnabled
, just by looking at the property name you know exactly what it means, how to use it, and what type it is. It makes your life easier.
So instead, I recommend you make your boolean property an actual boolean:
private bool _isActive;
public bool IsActive {
get { return _isActive; }
set { _isActive = value; }
}
XAML:
<Style.Triggers>
<DataTrigger Binding="{Binding IsActive}" Value="false">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsActive}" Value="true">
<Setter Property="Background" Value="Green"></Setter>
</DataTrigger>
</Style.Triggers>
If you wan to display the strings "Aktiv" and "Inaktiv" somewhere in the UI, you can do that with another trigger, or with a readonly property called something like ActiveDisplayString
.
You should probably be implementing INotifyPropertyChanged as well in that OPCItem
class; that way, you can change the property values after they're in the grid, and the UI will reflect the changes.
Upvotes: 2
Reputation: 10339
The value of your Active
property is never "true"
nor "false"
, so the triggers are never actually triggered. You should modify the expected values of your triggers to reflect the values that Active
might take (which are "Aktiv"
and "Inaktiv"
):
<DataTrigger Binding="{Binding Active}" Value="Inaktiv">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Active}" Value="Aktiv">
<Setter Property="Background" Value="Green"></Setter>
</DataTrigger>
Upvotes: 3