【问题标题】:How can I get the new position and size of a UIElement after performing a RenderTransform (Scale & Translate)?执行 RenderTransform (Scale & Translate) 后如何获取 UIElement 的新位置和大小?
【发布时间】:2014-03-09 11:15:49
【问题描述】:

我正在使用 RenderTransform 对图像执行缩放、平移和旋转。转换不是使用鼠标事件完成的,而是用户单击一个按钮,然后图像将按固定值缩放/平移/旋转。

我的问题是我想在每次执行缩放、平移或旋转时确定图像的新位置/大小。所以我在代码隐藏中添加了 Changed 事件。问题是如何获得新的位置/大小?

请看看我到目前为止做了什么:

XAML:

<Border x:Name="mainImageBorderCtrl" ClipToBounds="True">
     <Grid x:Name="imageGridCtrl">
          <Grid.RenderTransform>
               <TranslateTransform Changed="TranslateTransform_Changed"/>
          </Grid.RenderTransform>
          <Image x:Name="mainImageCtrl" RenderTransformOrigin="0.5, 0.5" Source="{Binding Image}">
               <Image.RenderTransform>
                    <TransformGroup>
                         <ScaleTransform Changed="ScaleTransform_Changed"/>
                         <RotateTransform />
                    </TransformGroup>
               </Image.RenderTransform>
          </Image>
     </Grid>
</Border>

请注意,我将 TranslateTransform 与 ScaleTransform 和 RotateTransform 分开,以免影响方向。

以下是 2 个更改的事件。在这里,我希望每次发生缩放或平移时都能获得新的位置/大小。但边界值不会改变。

代码隐藏

private Rect bounds;

private void TranslateTransform_Changed(object sender, EventArgs e)
{
     bounds = imageGridCtrl.TransformToAncestor(mainImageBorderCtrl).TransformBounds(new Rect(imageGridCtrl.RenderSize));
}

private void ScaleTransform_Changed(object sender, EventArgs e)
{
     bounds = imageGridCtrl.TransformToAncestor(mainImageBorderCtrl).TransformBounds(new Rect(imageGridCtrl.RenderSize));
}

编辑:我的目标是限制边框控件内图像的平移(平移),这就是为什么我需要在每次转换后获取图像的边界,无论转换是什么,这样我就可以检查Image的边界是否超出了Border。

【问题讨论】:

  • ScaleTransform 不会影响边界,因为边界是相同的。它只是内容被缩放。虽然TranslateTransform 确实对我有用,但它显示LeftTop 将在新的范围内更新。您没有观察到 TranslateTransform 的相同行为吗?
  • 啊,是的。 ScaleTransform 是我的问题。我的目标是限制边界控件内图像的平移(平移)。这就是为什么我需要知道图像的边界。
  • 我已经发布了答案。看看有没有帮助。

标签: c# wpf xaml


【解决方案1】:

TranslateTransform 正在生成正确的边界。但是,对于ScaleTransform,您将获得控制imageGridCtrl 的界限,但转换被添加为控制mainImageCtrl 的子级。

所以您应该使用mainImageCtrl 代替imageGridCtrl 以获得正确的界限

bounds = mainImageCtrl.TransformToAncestor(mainImageBorderCtrl)
                      .TransformBounds(new Rect(mainImageCtrl.RenderSize));

【讨论】:

  • 令人惊讶的是,我刚刚在调试时才意识到这一点。 :D 感谢您的澄清和帮助。我将投票作为正确答案。
【解决方案2】:

转换更改事件触发得太早。您应该连接到图像控件的LayoutUpdated 事件。然后试试:

mainImageCtrl.TransformToAncestor(mainImageBorderCtrl)
    .TransformBounds(new Rect(mainImageCtrl.RenderSize))

【讨论】:

  • 问题不在于 Changed 事件,而在于获取边界。无论您应用渲染转换多少次,边界的位置/大小始终与原始位置/大小相同。
猜你喜欢
  • 2011-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多