为什么LayoutTransform不会在旋转时更改顶点坐标(x1,y1)

时间:2017-07-10 19:24:36

标签: wpf xaml rotatetransform rendertransform layouttransform

我有一个包含形状(路径)的画布,其中我在布局转换中使用rotatetransform绑定角度。

当鼠标悬停在形状上(由我的路径生成)时,我在画布上生成MouseRightButtonUp,然后右键单击我使用布局变换旋转90度。

但它的行为类似于Render变换,因为我的绑定canvas.left和canvas.top在鼠标右键单击旋转后不会更新/更改 而角度变化了。 我的代码在这里:

<Canvas Name="OuterCanvas" Background="Green"  Height="700" Width="1000"  >
    <ItemsControl  AllowDrop="True"  x:Name="itemsCtrl" ItemsSource="{Binding ShapesCollection,Mode=TwoWay}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas ClipToBounds="True" IsItemsHost="True"  Height="700" Width="1000" Background="Transparent" x:Name="dragCanvas">
                    <i:Interaction.Triggers>                                          
                        <i:EventTrigger EventName="MouseRightButtonUp">
                            <ie:CallMethodAction MethodName="MouseRightButtonUpEventHandler" TargetObject="{Binding}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>                                          
                </Canvas>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Path  x:Name="im" Canvas.Left="{Binding Path=Canvas_Left , Mode=TwoWay}"
                      Canvas.Top="{Binding Path=Canvas_Top , Mode=TwoWay}"
                      Fill="{Binding Fill}"  Stroke="{Binding Stroke}"
                      StrokeThickness="{Binding StrokeThickness}" 
                      Data="{Binding Path=Data,Mode=TwoWay}">                                       
                    <Path.LayoutTransform>
                        <RotateTransform Angle="{Binding Path=Angle , Mode=TwoWay}"/>
                    </Path.LayoutTransform>                                             
                </Path>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="Canvas.Left" Value="{Binding Path=Canvas_Left , Mode=TwoWay}" />
                <Setter Property="Canvas.Top" Value="{Binding Path=Canvas_Top , Mode=TwoWay}" />
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>
</Canvas>

在viewmodel中调用的旋转方法是:

   public void MouseRightButtonUpEventHandler(object sender, MouseButtonEventArgs e)
    {
        e.Handled = true;
        ElementBeingDragged = e.Source as UIElement;
        if (ElementBeingDragged is System.Windows.Shapes.Path)
            if (ElementBeingDragged != null)
            {
                if (ElementBeingDragged.AllowDrop)
                {
                    var rotateTransform = ((System.Windows.Shapes.Path)ElementBeingDragged).LayoutTransform as RotateTransform;
                    if (rotateTransform == null)
                    {
                        (e.Source as FrameworkElement).LayoutTransform = new RotateTransform();                            
                    }
                    ((System.Windows.Shapes.Path)ElementBeingDragged).LayoutTransform = rotateTransform;
                    ((System.Windows.Shapes.Path)ElementBeingDragged).RenderTransformOrigin = new Point(0.5, 0.5);
                    rotateTransform.Angle += 90;
                }
                 ((System.Windows.Shapes.Path)ElementBeingDragged).UpdateLayout();//.LayoutUpdated();
                isDragInProgress = false;
                Mouse.Capture(null);
            }

    }

为什么Canvas.Left和Canvas.Top即使在角度变化位置改变之后也永远不会更新?   (假设矩形有A(x1,y1) B(x2,y2) , c(x3,y3) D(x4,y4),那么在旋转90度后它必须是A(x2,y2) B(x3,y3) , c(x4,y4) D(x1,y1) 为什么我的模型下面的Canvas.Left和Canvas.Top永远不会更新?

   public class Shapes :ICloneable
    { private double angle;
        public double Angle
        {
            get { return angle; }//Updates on rotation
            set
            {
                angle = value;
                RaisePropertyChanged("Angle");
            }
        }
        public double canvas_Top { get; set; }
        public double Canvas_Top
        {
            get { return canvas_Top; }//Never updates on rotation
            set
            {
                canvas_Top = value;
                RaisePropertyChanged("Canvas_Top");
            }
        }
        private double canvas_Left;
        public double Canvas_Left
        {
            get { return canvas_Left; } //Never updates on rotation
            set
            {
                canvas_Left = value;
                RaisePropertyChanged("Canvas_Left");
            }
        }
    }

这种行为在Rendertransform中是预期的,但是为什么在这种情况下LayoutTransform的行为类似于Rendertransform,因为我使用了LayOutTranform

1 个答案:

答案 0 :(得分:1)

变换不会更改基础坐标或“控制属性”。您可以将其视为在基础属性上应用蒙版,该属性可计算新位置或值,但不会更改原始位置或值。

例如:如果我有一个边长为2的正方形,则应用2的缩放变换。原始边长保持= 2。变换将计算新的边长为4,并以4的大小显示正方形。如果我删除变换,则正方形将是原始大小2。 要与您的90度旋转示例进行比较,虽然正确的是x1,y1和x2,y2的渲染值发生了变化,但基础值却没有。即从视觉上看,它们会发生变化,但变换是导致视觉变化的原因。

RenderTransform .vs之间的区别。 LayoutTransform主要发生在 WHEN 这些计算发生时(即我将方形边乘以2,或将矩形旋转90度)。两者仍然不会调整其他属性的来源。看Here获得一个很好的解释。 (我确定会有更多的差异;但这是我认为混乱正在发生的地方)

如果要从变换中实际调整Canvas.TopCanvas.Left属性,则需要将变换应​​用于这些值,然后使用Transform中的计算值设置属性。