1

我正在尝试在 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。有解决办法吗?有针对这种情况的最佳实践吗?

4

2 回答 2

6

您可以绑定 RenderTransform 本身,而不是绑定 RenderTransform 的 ScaleX 和 ScaleY 属性。问题是源是一个双精度值,你需要一个变换。因此,您需要能够将双精度转换为 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,因此您可以使用具有 RelativeSource 作为 TemplatedParent 的常规 Binding。像这样:

    <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>
于 2009-09-09T22:22:37.170 回答
1

假设您总是使用像矩形这样的简单项目,您可以将矩形的高度和宽度绑定到进度,然后使用绑定转换器相应地调整值

于 2009-09-09T20:20:53.733 回答