Reputation: 27615
I designed a battery level indicator consisting of a Border inside another Border.
The Width of inner Border is Multi-Bound to the outer Border ActualWidth
and the battery value itself (from DataContext
, ranging from 0.0 to 1.0):
<Border x:Name="BatteryChargeContainer">
<Border x:Name="BatteryCharge" Margin="1" HorizontalAlignment="Left" Background="Gray">
<Border.Width>
<MultiBinding Converter="{StaticResource NormalValueConverter}" FallbackValue="10">
<Binding Path="BatteryLevel"/>
<Binding Path="ActualWidth" ElementName="BatteryChargeContainer"/>
</MultiBinding>
</Border.Width>
</Border>
</Border>
==================
class NormalValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (values.Any(v => v == null))
return null;
var v1 = values[0];
var v2 = values[1];
double valor = System.Convert.ToDouble(v1);
double measure = System.Convert.ToDouble(v2);
return valor * measure;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Now I want to make something similar for the Background
property, with another IMultiValueConverter. The color should be calculated like this:
These colors are defined as Resources, because I absolutely don't want to declare them in the code, so my question is:
If the colors are defined as resources, and the actual applied color is calculated in the MultiBind Converter, how can I apply color based on the value returned, or else have the MultiConverter assess the available colors and return the selected color itself?
Upvotes: 2
Views: 256
Reputation: 585
You could use Triggers with a converter. The converter would return true if the value is greater than a given number. Here an example :
<Border x:Name="BatteryChargeContainer">
<Border x:Name="BatteryCharge" Margin="1" HorizontalAlignment="Left" Background="Gray">
<Border.Style>
<Style TargetType="Border">
<Setter RED.../>
<Style.Triggers>
<DataTrigger Binding="{Binding yourBinding, Converter=theConverter, ConverterParameter=0.3}" Value="true">
<Setter ORANGE... />
</DataTrigger>
<DataTrigger Binding="{Binding yourBinding, Converter=theConverter, ConverterParameter=0.6}" Value="true">
<Setter YELLOW... />
</DataTrigger>
<DataTrigger Binding="{Binding yourBinding, Converter=theConverter, ConverterParameter=0.8}" Value="true">
<Setter GREEN... />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
This should work because all the triggers will be tested in order. So for instance, if you feed the value 0.9, it will return true on every trigger, so it will change the color to orange, then, yellow and then green, so you'll have the green color as a result.
Small but significant detail, in your converter, the parameter you will receive will be a string. You will need to cast it to a float before you test it with the value.
Hope this helps!
Upvotes: 2