WPF: Dynamic Actions in Template
I've defined a control Template for a progressbar to make it look like a thermometer ... now i want it to change its color when reaching a certain value (for example .. when the progressbar has the value 70, its color should change to yellow)
Currently the color of PART_Indicator is bound to the background color of the progressbar .. the backgroundcolor is changed in the ValueChanged Eventhandler, and so the color of the indicator changes too... is there a possibility to do this within the template only, so i dont need to use the ValueChanged Eventhandler?
<ControlTemplate x:Key="myThermometer" TargetType="{x:Type ProgressBar}">
<ControlTemplate.Resources>
<RadialGradientBrush x:Key="brushBowl" GradientOrigin="0.5 0.5">
<GradientStop Offset="0" Color="Pink" />
<GradientStop Offset="1" Color="Red" />
</RadialGradientBrush>
</ControlTemplate.Resources>
<Canvas>
<Path Name="PART_Track" Stroke="Black" StrokeThickness="5" Grid.Column="0">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Un开发者_如何学Pythonion">
<CombinedGeometry.Geometry1>
<RectangleGeometry Rect="10,40,130,20" RadiusX="5" RadiusY="5"/>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry Center="10,50" RadiusX="20" RadiusY="20"/>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
<Path Fill="{TemplateBinding Background}">
<Path.Data>
<EllipseGeometry Center="10,50" RadiusX="17" RadiusY="17"/>
</Path.Data>
</Path>
<Path Name="PART_Indicator" Fill="{TemplateBinding Background}" Grid.Column="0">
<Path.Data>
<RectangleGeometry Rect="22,43,115,15" RadiusX="5" RadiusY="5"/>
</Path.Data>
</Path>
<Canvas Canvas.Top="35" Canvas.Right="375">
<Canvas.RenderTransform>
<RotateTransform CenterX="120" CenterY="120" Angle="-270" />
</Canvas.RenderTransform>
<TextBlock FontWeight="Bold" FontSize="16" Foreground="Black" Text="{TemplateBinding Tag}"/>
</Canvas>
</Canvas>
</ControlTemplate>
<ProgressBar x:Name="progressBar" Background="{Binding RelativeSource={RelativeSource Self},Path=Value,Converter={StaticResource IntToBrushConverter}}" />
public class IntToBrushConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double val = (double)value;
if (val > 50)
return Brushes.Blue;
else
return Brushes.Green;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new Exception("Not Implemented");
}
#endregion
}
more or less - I'd write a custom ValueConverter that converts your progress value to a Color and bind the fill of the progress bar using this converter.
XAML:
Fill="{TemplateBinding Progress,
Converter={StaticResource ProgressToColorConverter}}"
Code:
[ValueConversion(typeof(int), typeof(Color))]
public class ProgressToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int progress = (int)value;
if (progress < 60)
return Color.Green;
else
return Color.Red;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
This code is just from the top of my head and hasn't been tested, but it should show the principles.
精彩评论