2009-09-09 68 views
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> 

然而,this forum thread指出TemplateBinding仅适用于FrameworkElements的衍生物。 ScaleTransform不是一个FrameworkElement。有没有解决这个问题的方法?任何有关这种情况的最佳实践?

回答

6

与其结合的scaleX和scaleY RenderTransform的属性,你可以绑定RenderTransform本身。 问题是源是一个双精度值,并且您需要一个变换。所以你需要能够将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(); 
    } 
} 

您不能指定的IValueConverter在TemplateBinding来使用,这样你就可以使用普通的绑定有作为的RelativeSource TemplatedParent。就像这样:

<Rectangle x:Name="ProgressPart" Fill="Blue" 
      RenderTransform="{Binding Path=Progress, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource converter1}}" > 

,你需要放置的IValueConverter在ControlTemplate中的根的资源,在绑定的范围:

<ControlTemplate TargetType="controls:ProgressBar"> 
    <Grid> 
     <Grid.Resources> 
      <local:TransformConverter x:Key="converter1" /> 
     </Grid.Resources> 
+0

非常感谢。比我在课堂上创建变换和绑定它们的解决方案好得多。 – 2009-09-10 08:34:00

1

假设你一直使用简单的,像一个矩形,你可以在矩形的高度和宽度绑定到进度,然后用结合转换器来调整值相应

相关问题