I have a MVVM binding for Border background where in I read Color names from a file in String format and convert them to Brush using the code:
Brush b1 = new SolidColorBrush((Color)ColorConverter.ConvertFromString("Red");
myItem.Background = b1;
Background is a property defined in ViewModel as:
public Brush Background
{
get { return _background; }
set
{
this._background = value;
RaisePropertyChanged("Background");
}
}
And it is accessed in XAML as:
<Border Background="{Binding Background}">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding Background}" Value="Red">
<Setter Property="Height" Value="40"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
The border is properly colored- no issues there.
The problem is DataTrigger is never triggered because when I see the value of this._background in set method, it is "#FFFF0000" and it is not equal to Brushes.Red (i tried converting value to SolidColorBrush and then compared with Brushes.Red, but it is not equal).
What is that I am doing wrong? What can I do to ensure that the color names that I read from a file are properly converted into Brushes.* so that my DataTrigger works fine.
Thanks,
RDV
Yes, Brushes.Red
is a SolidColorBrush
. Not a color, a brush. Confusion arises from the implicit conversion of the string "Red", in the XAML, into a Brush object. But a new SolidColorBrush
instance with a Color
that is also equal to #FFFF0000
will be a different instance of SolidColorBrush
, and they won't be "equal" to one another.
But you don't care which brush instance it is; you care about the color. So compare the color. (Brushes.Red.Color == Colors.Red) == true
. Color
is a value type, not a reference type, so two equivalent values will be considered equal.
<DataTrigger
Binding="{Binding Background.Color, RelativeSource={RelativeSource Self}}"
Value="Red">
Notice that Background
isn't a property of the DataContext
. That was a second thing that wasn't working with your code. You need to explicitly tell the Binding
to look not at the DataContext
, but at the control itself, to find the property referred to in the Path
. RelativeSource={RelativeSource Self}
does that. "Background.Color"
is the Path
parameter for the Binding
. Path
is the default, so you don't have to explicitly name it. But you could:
<DataTrigger
Binding="{Binding Path=Background.Color, RelativeSource={RelativeSource Self}}"
Value="Red">