Silverlight TemplateBinding到RotateTransform

时间:2010-01-23 13:45:13

标签: silverlight templates silverlight-3.0 controls

我正在尝试创建最简单的Silverlight模板控件,我似乎无法让TemplateBinding处理RotateTransform的Angle属性。

这是来自generic.xaml的ControlTemplate:

<ControlTemplate TargetType="local:CtlKnob">
  <Grid x:Name="grid" RenderTransformOrigin="0.5,0.5">
    <Grid.RenderTransform>
      <TransformGroup>
         <RotateTransform Angle="{TemplateBinding Angle}"/> <!-- This does not work -->
         <!-- <RotateTransform Angle="70"/> -->             <!-- This works -->
      </TransformGroup>
    </Grid.RenderTransform>
    <Ellipse Stroke="#FFB70404" StrokeThickness="19"/>
    <Ellipse Stroke="White" StrokeThickness="2" Height="16" VerticalAlignment="Top"
       HorizontalAlignment="Center" Width="16" Margin="0,2,0,0"/>
  </Grid>
</ControlTemplate>

这是C#:

using System.Windows;
using System.Windows.Controls;

namespace CtlKnob
{
  public class CtlKnob : Control
  {
    public CtlKnob()
    {
      this.DefaultStyleKey = typeof(CtlKnob);
    }

    public static readonly DependencyProperty AngleProperty = 
        DependencyProperty.Register("Angle", typeof(double), typeof(CtlKnob), null);

    public double Angle
    {
      get { return (double)GetValue(AngleProperty); }
      set { SetValue(AngleProperty,value); }
    }
  }   
}

4 个答案:

答案 0 :(得分:2)

这是一种解决方法:

public class TemplatedControl1 : Control
    {
        public TemplatedControl1()
        {
            this.DefaultStyleKey = typeof(TemplatedControl1);
        }

        public override void OnApplyTemplate()
        {
            var transform = this.GetTemplateChild("Transform1") as RotateTransform;
            transform.Angle = this.StartAngle;

            base.OnApplyTemplate();
        }

        public static readonly DependencyProperty StartAngleProperty =
        DependencyProperty.Register("StartAngle", typeof(double), typeof(TemplatedControl1), null);

        public double StartAngle
        {
            get { return (double)GetValue(StartAngleProperty); }
            set { SetValue(StartAngleProperty, value); }
        }

    }

和xaml:

<Style TargetType="local:TemplatedControl1">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:TemplatedControl1">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">

                        <Canvas>
                            <Polyline Fill="Black" >
                                <Polyline.RenderTransform>
                                    <RotateTransform x:Name="Transform1" />
                                </Polyline.RenderTransform>
                            </Polyline>
                        </Canvas>


                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

答案 1 :(得分:1)

Henrik已准备就绪,但我会解释为什么必要。

目前在Sliverlight 3中,这种绑定要求接收绑定的对象是FrameworkElement。其FrameworkElement SetBinding方法允许此内容工作。

RotateTransform虽然DependencyObject不是FrameworkElement,因此无法参与此类绑定。 Silverlight 4允许绑定在DependencyObject上工作,所以理论上这种代码应该在SL4中工作。我将不得不尝试看看是否属实。

答案 2 :(得分:0)

感谢Anthony解释为什么它不起作用。

感谢Henrik的解决方法,它解决了一半的问题:现在可以从Xaml设置角度。但是,它仍然无法以编程方式设置,但缺少的位现在很容易。

以下是完整的解决方案:

public class CtlKnob : Control
{
  public CtlKnob()
  {
    this.DefaultStyleKey = typeof(CtlKnob);
  }

  public static readonly DependencyProperty AngleProperty =
    DependencyProperty.Register("Angle", typeof(double), typeof(CtlKnob),
      new PropertyMetadata(AngleChanged));

  public double Angle
  {
    get { return (double)GetValue(AngleProperty); }
    set { SetValue(AngleProperty,value); }
  }

  public override void OnApplyTemplate()
  {
    base.OnApplyTemplate();
    var transform = this.GetTemplateChild("RotateTransform") as RotateTransform;
    transform.Angle = this.Angle;
  } 

  private static void AngleChanged( DependencyObject dobj,
                                    DependencyPropertyChangedEventArgs e )
  {
    var knob = dobj as CtlKnob;
    var rotateTransform = knob.GetTemplateChild("RotateTransform") as 
      RotateTransform;
    if (rotateTransform != null)
      rotateTransform.Angle = (double)e.NewValue;
  }
}

答案 3 :(得分:0)

在Silverlight 3中,您只能绑定到FrameworkElements而不能绑定到DependencyObjects。 RotateTransform不是FrameworkElement。

Silverlight 4支持绑定到DependencyObjects,因此适用于Silverlight 4。

如果你可以升级到Silverlight 4,我会考虑它。否则,许多人已经发布了Silverlight 3的变通方法。