为什么 LayoutTransform 在旋转时不改变顶点坐标 (x1,y1)
Why LayoutTransform do not change vertice coordinates (x1,y1) on rotation
我有一个 canvas,其中包含形状(路径),其中我在布局变换中将角度与 rotatetransform 绑定。
当鼠标悬停在形状(由我的路径生成)上时,我在 canvas 上生成 MouseRightButtonUp 然后右键单击我使用布局变换旋转 90 度。
但它的行为类似于渲染变换,因为我的绑定 canvas.left 和 canvas.top 在形状上右键单击鼠标旋转后不会 updates/change
而角度会改变。
我的代码在这里:
<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>
视图模型中调用的旋转方法是:
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
转换不会更改基础坐标或控件属性。可以把它想象成在计算新位置或值但不更改原始值的基础属性上应用掩码。
例如:如果我有一个边长为 2 的正方形。然后应用 2 的缩放变换。原始边长保持 =2。变换将计算新的边长 4 并以 4 的大小显示正方形。如果我删除变换,正方形将是原始大小 2。
与您的 90 度旋转示例相比,虽然您认为 x1,y1 和 x2,y2 的渲染值发生变化是正确的,但基础值没有变化。 IE。从视觉上你会看到它们发生变化,但变换才是造成视觉变化的原因。
RenderTransform .vs. 之间的区别LayoutTransform 主要发生在 WHEN 这些计算发生时(即我什么时候将我的正方形边乘以 2,或者将我的矩形旋转 90 度)。两者都不会调整您其他属性的来源。查看 Here 以获得很好的解释。
(我确定还有更多差异;但这是我认为正在发生混乱的地方)
如果您想实际调整来自转换的 Canvas.Top
或 Canvas.Left
属性,您需要将转换应用于这些值,然后使用转换中的计算值设置属性.
我有一个 canvas,其中包含形状(路径),其中我在布局变换中将角度与 rotatetransform 绑定。
当鼠标悬停在形状(由我的路径生成)上时,我在 canvas 上生成 MouseRightButtonUp 然后右键单击我使用布局变换旋转 90 度。
但它的行为类似于渲染变换,因为我的绑定 canvas.left 和 canvas.top 在形状上右键单击鼠标旋转后不会 updates/change 而角度会改变。 我的代码在这里:
<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>
视图模型中调用的旋转方法是:
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
转换不会更改基础坐标或控件属性。可以把它想象成在计算新位置或值但不更改原始值的基础属性上应用掩码。
例如:如果我有一个边长为 2 的正方形。然后应用 2 的缩放变换。原始边长保持 =2。变换将计算新的边长 4 并以 4 的大小显示正方形。如果我删除变换,正方形将是原始大小 2。 与您的 90 度旋转示例相比,虽然您认为 x1,y1 和 x2,y2 的渲染值发生变化是正确的,但基础值没有变化。 IE。从视觉上你会看到它们发生变化,但变换才是造成视觉变化的原因。
RenderTransform .vs. 之间的区别LayoutTransform 主要发生在 WHEN 这些计算发生时(即我什么时候将我的正方形边乘以 2,或者将我的矩形旋转 90 度)。两者都不会调整您其他属性的来源。查看 Here 以获得很好的解释。 (我确定还有更多差异;但这是我认为正在发生混乱的地方)
如果您想实际调整来自转换的 Canvas.Top
或 Canvas.Left
属性,您需要将转换应用于这些值,然后使用转换中的计算值设置属性.