Canvas resize上的ScaleTransform以比儿童更高的速率缩小Canvas

时间:2013-03-11 17:29:34

标签: c# wpf winforms wpf-controls

我有一个WPF控件停靠在WinForms应用程序中的WPF主机控件中。 WPF控件设置为水平和垂直拉伸,主机控件停靠在锚定组框中。

我的WPF控件有一个Canvas,它填充了我用来放置子节点的空间,这些子节点是从Canvas派生的自定义类。

我订阅了主Canvas的SizeChanged事件,并应用了一个缩放变换,以便在调整控件大小时画布及其子画面会以缩放方式缩小和增长,这是有效的,但由于某种原因,父画布正在以比孩子高得多的速度萎缩,由于比例的原因,孩子们在某个时刻会从画布上掉下来。

这是我的代码:

    private void EditorCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        if (e.PreviousSize.Width == 0)
            return;
        double YDiff = e.PreviousSize.Height / e.NewSize.Height;
        double XDiff = e.PreviousSize.Width / e.NewSize.Width;

        Scale.ScaleY /= YDiff;
        Scale.ScaleX /= XDiff;
    }

画布的子画面似乎以正确的速度缩放,画布似乎以更高的速率缩放。

有没有人看到任何理由/知道为什么会发生这种情况?

行为图片......注意较小面板后面的空白区域

IMG

缩放 IMG

2 个答案:

答案 0 :(得分:4)

此:

  

我订阅了主要的Canvas'TizeChanged事件并应用了一个比例   转换,以使画布及其子画片收缩和生长   调整控件大小时的缩放,这是有效的,但是   由于某种原因,父画布正在以更高的速度收缩   比起孩子们,让孩子们从画布上掉下来   由于比例率,这一点。

Viewbox的作用。将Viewbox作为根元素放在WPF可视化树中。并将其Stretch属性设置为适合您需要的属性。并删除所有大小计算。 WPF不需要大小计算。

答案 1 :(得分:1)

看起来你缺少一些中间步骤(即一些尺寸变化)。如果您的应用程序无法足够快地处理大小更改事件,Windows可能会跳过中间的一些以便赶上

例如,假设您的应用程序以1000的高度开始。然后快速更改为100,但在此过程中它会经历多个中间大小(500,250,125)。如果您错过了其中的一两个,那么您在ScaleY计算中会得到类似的结果:

0. Height = 1000; ScaleY = 1
1. Height: 1000 > 500; ScaleY = 1/(1000/500) = 0.5
2. [misses 250]; no scaleY adjustment
3. Height: 250 > 125; ScaleY = 0.5 / (250/125) = 0.25  // when it should actually be .125
4. Height: 125 > 100; ScaleY = 0.25 / (125/100) = 0.2  // when it should actually be 0.1

您应该存储并使用原始大小并计算绝对值,而不是连续差异 ..