将 RotateTransform 应用于 Canvas 中的 WPF TextBlock 时,TranslateTransform 未“保留”

问题描述 投票:0回答:1

在画布中绘制一些 TextBlock 以及其他形状时,我使用 TranslateTransform 放置它们。 我没有在 XAML 中执行此操作,因为我将在运行时生成对象。

Point origin, rotated;
origin.X = center.X;
origin.Y = center.Y + radius;
rotated.X = (Math.Cos(angle * Math.PI / 180) * (origin.X - center.X) - Math.Sin(angle * Math.PI / 180) * (origin.Y - center.Y) + center.X);
rotated.Y = (Math.Sin(angle * Math.PI / 180) * (origin.X - center.X) + Math.Cos(angle * Math.PI / 180) * (origin.Y - center.Y) + center.Y);

TranslateTransform translateTransf = new TranslateTransform() { X = rotated.X, Y = rotated.Y };
textBlock.RenderTransform = translateTransf;
plotCanvas.Children.Add(textBlock);

Objects translated, but not rotated

然后在另一个事件中,我对画布中的对象应用旋转,并将画布的绝对值传递给 CenterX 和 CenterY 以确定所有旋转的中心。

RotateTransform rotateTransf = new RotateTransform(angleRotation) { CenterX = plotCanvas.ActualHeight / 2, CenterY = plotCanvas.ActualWidth / 2 };
foreach (TextBlock childBlock in plotCanvas.Children.OfType<TextBlock>())
    childBlock.RenderTransform = rotateTransf;
// Other objects are rotated fine around the canvas center

当事件触发时,之前应用的 TranslateTransform 的效果会以某种方式“丢失”,文本块被放置在画布的 (0, 0) 位置,然后旋转。其他形状旋转得很好,我使用椭圆和直线作为几何图形,并将它们放置在我需要的位置,并且不受 TranslateTransform 的影响。 请注意,“二次旋转”应用于(捆绑在一起的)文本,而我希望它保持水平,然后我将应用另一个旋转以使其指向画布的中心。

After applying a rotation, the text translation is

为了在旋转(或累积变换)之前“保留”初始变换,我做错了什么或遗漏了什么,为什么会发生这种“二次旋转”?

c# wpf
1个回答
0
投票

据我所知,从研究这个主题的时间来看,我设法做到了最有效的,更新 TransformGroup 的元素(在我的例子中,是 RotateTransform),而不是将变换重新应用到 RenderTransform。 感谢@emocht 让我了解 TransformGroup

对于那些感兴趣的人,这一行改变了 RotationTransform 的角度,它是我的 TransformGroup 的第二个子级(第一个是 TranslateTransform):

((RotateTransform)((TransformGroup)childBlock.RenderTransform).Children[1]).Angle = angleRotation;

这是假设我已经填充了 CenterX 和 CenterY。如果不是,那么只需在上面的行之前添加以下内容并更改为您需要的内容(在我的情况下,我围绕画布中心旋转):

((RotateTransform)((TransformGroup)childBlock.RenderTransform).Children[1]).CenterX = cv.ActualHeight / 2; ((RotateTransform)((TransformGroup)childBlock.RenderTransform).Children[1]).CenterY = cv.ActualWidth / 2;
这个想法来自以下 S.O.邮政:

C# 中的 WPF 更改转换

© www.soinside.com 2019 - 2024. All rights reserved.