2010-01-23 31 views
1

我想创建最简单的Silverlight模板控件,并且我似乎无法使TemplateBinding在RotateTransform的Angle属性上工作。Silverlight TemplateBinding RotateTransform

下面是generic.xaml的控件模板:

<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); } 
    } 
    } 
} 

回答

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> 
+0

+1不太确定为什么您将'Angle'重命名为'StartAngle'? – AnthonyWJones 2010-01-23 21:59:52

+0

哈哈,好问题。当我开始玩代码时,我认为它没有起作用的原因是属性名称冲突或什么。我很快意识到这是一个愚蠢的想法,但到那时我已经重新命名了这个事物,因为我本性就是一个懒惰的人,所以我就这样离开了它。抱歉。 :) – 2010-01-23 23:40:39

1

亨利克已经准备好了答案,但我会解释为什么它是必要的。

目前在Sliverlight 3中,这种绑定要求接收绑定的对象是FrameworkElement。它的FrameworkElementSetBinding方法,允许这个东西工作。

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

+0

不,它不是。 'o' – herzmeister 2010-11-02 16:06:34

0

谢谢安东尼解释为什么它不起作用。

感谢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; 
    } 
} 
0

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

Silverlight 4的支持结合DependencyObjects,所以此工程在Silverlight 4

如果你可以升级到Silverlight 4中,我会考虑它。否则,许多人已经发布了适用于Silverlight 3的解决方法。

+0

我发现这些解决方法之一即使与WP7/MVVM-Light项目一起使用也很有效,详情请见:http://sharpgis.net/post/2009/05/04/Using-surrogate-binders -in-Silverlight.aspx – Stonetip 2011-03-04 19:14:03

相关问题