【问题标题】:MatrixTransform in combination with Width/Height of a CanvasMatrixTransform 与画布的宽度/高度相结合
【发布时间】:2014-03-04 11:09:26
【问题描述】:

在 Canvas 上放大绘图时,我需要显示滚动条。
Canvas 位于 ScrollViewer 中,我增加了 Canvas 的宽度/高度,以便出现 scollbars(否则它们不会出现)。

要放大 1.1 倍,我使用以下代码:

Matrix m = this.LayoutTransform.Value;
if (e.Delta > 0) f = 1.1;
else f = 1.0 / 1.1;
m.Scale(f, f);
this.LayoutTransform = new MatrixTransform(m);
this.Height = this.ActualHeight * f;
this.Width = this.ActualWidth * f;

事实证明,画布变得太大了。绘图放大了 10%,但宽度似乎变成了 20%,更像 1.1 的平方。所以我使用Math.Sqrt(f); 而不是f

谁能解释它为什么会这样?

【问题讨论】:

  • 您似乎应用了两次缩放因子,第一次是 LayoutTransform,第二次是乘以 Width 和 Height。你应该只做其中之一,最好只做 LayoutTransform。
  • 然后滚动条不出现(这是一个要求)。

标签: wpf canvas scrollviewer matrix-transform


【解决方案1】:

您应该只更改 Canvas 的 LayoutTransform,就像在这个简化的示例中一样:

<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
    <Canvas Width="1000" Height="1000" Background="Transparent"
            MouseWheel="Canvas_MouseWheel">
        <Canvas.LayoutTransform>
            <MatrixTransform/>
        </Canvas.LayoutTransform>
    </Canvas>
</ScrollViewer>

MouseWheel 事件处理程序:

private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
    var element = (FrameworkElement)sender;
    var transform = (MatrixTransform)element.LayoutTransform;
    var matrix = transform.Matrix;
    var scale = e.Delta >= 0d ? 1.1 : (1d / 1.1);

    matrix.Scale(scale, scale);
    transform.Matrix = matrix;

    e.Handled = true;
}

【讨论】:

  • 没有Width="1000" Height="1000" 是否可以工作?我的画布没有初始尺寸,它也适合其父尺寸和绘图尺寸。
  • 它必须有一个初始大小,否则 ScrollViewer 没有意义。但是,您可以在可用的代码中设置初始大小。
  • 还有一个问题:当我将 Transform 重置回 Identity 时,滚动条仍然可见,而最初它们不可见(这很好)并且 Canvas 大小没有改变。
  • 还有一个问题:使用 RenderTransform 而不是 LayoutTransform 时,尽管设置了 Width&Heigth,但不会出现 scollbars。
  • 第一个问题:不看你的代码很难说。第二:RenderTransform 不会影响布局,但你需要它。你不能在这里使用 RenderTransform。
猜你喜欢
  • 2018-06-21
  • 2020-08-30
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多