2009-09-09 70 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

假設你一直使用簡單的,像一個矩形,你可以在矩形的高度和寬度綁定到進度,然後用結合轉換器來調整值相應

相關問題