绑定到ControlTemplate中的变换

Jam*_*Hay 1 silverlight templatebinding

我正在尝试在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>
Run Code Online (Sandbox Code Playgroud)

但是,此论坛帖子声明TemplateBinding仅适用于FrameworkElements的衍生物.ScaleTransform不是FrameworkElement.有没有解决这个问题?针对这种情况的最佳做法是什么?

Kei*_*ney 6

您可以绑定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();
    }
}
Run Code Online (Sandbox Code Playgroud)

您不能指定要在TemplateBinding中使用的IValueConverter,因此您可以将常规Binding与RelativeSource一起用作TemplatedParent.像这样:

    <Rectangle x:Name="ProgressPart" Fill="Blue" 
           RenderTransform="{Binding Path=Progress, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource converter1}}" >
Run Code Online (Sandbox Code Playgroud)

并且您需要将IValueConverter放在ControlTemplate的根资源中,在Binding的范围内:

<ControlTemplate TargetType="controls:ProgressBar">
    <Grid>
        <Grid.Resources>
            <local:TransformConverter x:Key="converter1" />
        </Grid.Resources>
Run Code Online (Sandbox Code Playgroud)