开发者

Rotate also resizes?

I have this xaml

    <Image Width="240" Height="240">                
        <Image.Source>                    
            <DrawingImage>
                <DrawingImage.Drawing>
                    <DrawingGroup>
                开发者_运维知识库        <DrawingGroup>
                            <DrawingGroup>
                                <DrawingGroup.Transform>
                                    <TransformGroup>
                                        <RotateTransform Angle="-15" CenterX="120" CenterY="120" />
                                        <TranslateTransform Y="-20" />
                                    </TransformGroup>
                                </DrawingGroup.Transform>

                                <ImageDrawing ImageSource="Images\pNxVK.png" Rect="0,0,240,240" />
                            </DrawingGroup>

                            <DrawingGroup.ClipGeometry>
                                <EllipseGeometry Center="120,120" RadiusX="60" RadiusY="60" />
                            </DrawingGroup.ClipGeometry>
                        </DrawingGroup>

                        <DrawingGroup>
                            <DrawingGroup>
                                <!--<DrawingGroup.Transform>
                                    <RotateTransform Angle="-15" CenterX="120" CenterY="120" />
                                </DrawingGroup.Transform>-->
                                <ImageDrawing ImageSource="Images\zUr8D.png" Rect="0,0,240,240" />
                            </DrawingGroup>                                        
                            <ImageDrawing ImageSource="Images\XPZW9.png" Rect="0,0,240,240" />
                        </DrawingGroup>                                
                    </DrawingGroup>
                </DrawingImage.Drawing>
            </DrawingImage>
        </Image.Source>
    </Image>

The result of that xaml is (Correct size)

Rotate also resizes?

If I uncomment the rotate transform in the xaml above i get this (Wrong size)

Rotate also resizes?


The drawings are rectangles. And a rotated rectangle has bigger bounding box than a non-rotated one, so it has to be scaled to fit the original boundaries.

You can resolve this by specifying ClipGeometry of the outermost DrawingGroup - just clip it to the original bounds.

<DrawingGroup.ClipGeometry>
    <RectangleGeometry Rect="0 0 240 240" />
</DrawingGroup.ClipGeometry>


If its not working when we do it in xaml, maybe it will work from code:

Xaml:

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Test"
        Title="MainWindow" Height="350" Width="525">
  <StackPanel>
    <TextBlock Text="Rotate:" />
    <Slider Minimum="-360" Maximum="360" Value="{Binding ElementName=CrossHair, Path=Rotate, Mode=TwoWay}" />
    <TextBlock Text="TranslateX:" />
    <Slider Minimum="-200" Maximum="200" Value="{Binding ElementName=CrossHair, Path=TranslateX, Mode=TwoWay}" />
    <TextBlock Text="TranslateY:" />
    <Slider Minimum="-200" Maximum="200" Value="{Binding ElementName=CrossHair, Path=TranslateY, Mode=TwoWay}" />

    <local:CrossHair Width="240" Height="240" x:Name="CrossHair" />
  </StackPanel>
</Window>

Code-behind:

namespace Test
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
    }
  }

  public class CrossHair : FrameworkElement
  {
    public double TranslateX
    {
      get { return (double)GetValue(TranslateXProperty); }
      set { SetValue(TranslateXProperty, value); }
    }

    public static readonly DependencyProperty TranslateXProperty = DependencyProperty.Register("TranslateX", typeof(double), typeof(CrossHair), new UIPropertyMetadata(0.0, PropertyChangedCallback));

    public double TranslateY
    {
      get { return (double)GetValue(TranslateYProperty); }
      set { SetValue(TranslateYProperty, value); }
    }

    public static readonly DependencyProperty TranslateYProperty = DependencyProperty.Register("TranslateY", typeof(double), typeof(CrossHair), new UIPropertyMetadata(-20.0, PropertyChangedCallback));

    public double Rotate
    {
      get { return (double)GetValue(RotateProperty); }
      set { SetValue(RotateProperty, value); }
    }

    // This will result in an OnRender call.
    public static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      FrameworkElement element = d as FrameworkElement;
      if (element != null)
        element.InvalidateVisual();
    }

    public static readonly DependencyProperty RotateProperty = DependencyProperty.Register("Rotate", typeof(double), typeof(CrossHair), new UIPropertyMetadata(-15.0, PropertyChangedCallback));

    protected override void OnRender(DrawingContext ctx)
    {
      base.OnRender(ctx);

      double renderWidht = this.ActualWidth;
      double renderHeight = this.ActualHeight;

      //Debug Rectangle, you should comment it.
      //ctx.DrawRectangle(Brushes.Black, new Pen(Brushes.Black, 1), new Rect(0, 0, renderWidht, renderHeight));

      // First Layer: clipped background.
      ctx.PushClip(new EllipseGeometry(new Point(renderWidht / 2.0, renderHeight / 2.0), renderWidht / 4.0, renderHeight / 4.0));
      ctx.PushTransform(new TransformGroup()
                            {
                              Children = new TransformCollection(2)
                                {
                                  new TranslateTransform(TranslateX, TranslateY),
                                  new RotateTransform(Rotate, renderWidht / 2.0, renderHeight / 2.0)
                                }
                            });

      ctx.DrawImage(new BitmapImage(new Uri("pack://application:,,,/Images/pNxVK.png")), new Rect(0, 0, renderWidht, renderHeight));
      ctx.Pop();// Pop the clipping
      ctx.Pop();// Pop the translate

      // 2nd Layer:
      ctx.DrawImage(new BitmapImage(new Uri("pack://application:,,,/Images/XPZW9.png")), new Rect(0, 0, renderWidht, renderHeight));
      // 3rd Layer:
      ctx.DrawImage(new BitmapImage(new Uri("pack://application:,,,/Images/zUr8D.png")), new Rect(0, 0, renderWidht, renderHeight));
    }
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜