绑定到ControlTemplate中的变换
-
05-07-2019 - |
题
我正在尝试在Silverlight中创建一个自定义控件,动态缩放其ControlTemplate中的元素。 ControlTemplate的第一次尝试看起来像这样:
<ControlTemplate TargetType="controls:ProgressBar">
<Grid>
<Rectangle x:Name="TrackPart" Fill="{TemplateBinding Background}" HorizontalAlignment="Left" />
<Rectangle x:Name="ProgressPart" Fill="Blue" >
<Rectangle.RenderTransform>
<ScaleTransform ScaleX="{TemplateBinding Progress}" />
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</ControlTemplate>
但是,这个论坛主题指出TemplateBinding仅适用于FrameworkElements的衍生产品。 ScaleTransform不是FrameworkElement。有没有解决这个问题?那种情况的最佳做法是什么?
解决方案
您可以绑定RenderTransform本身,而不是绑定RenderTransform的ScaleX和ScaleY属性。 问题是源是一个double值,你需要一个Transform。所以你需要能够将double转换为ScaleTransform。您可以创建一个IValueConverter来执行此操作:
public class TransformConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double)
{
double d = (double)value;
return new ScaleTransform { ScaleY = d, ScaleX = d };
}
else
{
return new ScaleTransform();
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
您无法指定要在TemplateBinding中使用的IValueConverter,因此您可以将常规Binding与RelativeSource一起用作TemplatedParent。像这样:
<Rectangle x:Name="ProgressPart" Fill="Blue"
RenderTransform="{Binding Path=Progress, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource converter1}}" >
并且你需要将IValueConverter放在ControlTemplate根目录的资源中,在Binding的范围内:
<ControlTemplate TargetType="controls:ProgressBar">
<Grid>
<Grid.Resources>
<local:TransformConverter x:Key="converter1" />
</Grid.Resources>
其他提示
假设您总是使用像矩形这样的简单项目,可以将矩形的高度和宽度绑定到进度,然后使用绑定转换器相应地调整值
不隶属于 StackOverflow