Шаблон Silverlight Привязка к RotateTransform - PullRequest
1 голос
/ 23 января 2010

Я пытаюсь создать простейший шаблонный элемент управления Silverlight и не могу заставить TemplateBinding работать со свойством Angle объекта RotateTransform.

Вот ControlTemplate из 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); }
    }
  }   
}

Ответы [ 4 ]

2 голосов
/ 23 января 2010

Вот обходной путь:

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 голос
/ 24 января 2010

Хенрик все готово предоставил ответ, но я объясню, почему это необходимо.

В настоящее время в Sliverlight 3 такого рода привязка требует, чтобы объект, получающий привязку, был FrameworkElement. Это FrameworkElement, который имеет метод SetBinding, который позволяет этому материалу работать.

RotateTransform, хотя DependencyObject не является FrameworkElement и поэтому не может участвовать в такого рода связывании. Silverlight 4 позволяет привязке работать на DependencyObject, поэтому теоретически такой код должен работать в SL4. Я должен попробовать это, чтобы увидеть, правда ли это.

0 голосов
/ 24 января 2010

В Silverlight 3 вы можете связывать только с FrameworkElements, а не с DependencyObjects. RotateTransform не является FrameworkElement.

Silverlight 4 поддерживает привязку к объектам DependencyObjects, поэтому это работает в Silverlight 4.

Если вы сможете обновить до Silverlight 4, я бы рассмотрел это. В противном случае несколько человек опубликовали обходные пути для Silverlight 3.

0 голосов
/ 24 января 2010

Спасибо Энтони за объяснение, почему это не работает.

Спасибо Хенрику за обходной путь, он решает половину проблемы: теперь угол можно установить из 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;
  }
}
...