【问题标题】:Breaking cumulative transformations打破累积转换
【发布时间】:2014-06-09 16:10:33
【问题描述】:

我正在使用DrawingContext 对象来绘制一系列矩形。我的要求是这样的:

  1. 我要放置在 (100, 100) 的第一个矩形
  2. 第二个矩形我想放置在(200, 200)
  3. 我想放置在 (0, 0) 处的第三个矩形

我使用变换矩阵来实现如下:

  1. 要将第一个矩形定位在 (100, 100),我使用以下命令:

    drawingContext.PushTransform(new TranslateTransform(100, 100)); drawingContext.DrawRectangle(Brushes.Blue, null, new Rect(0, 0, 100, 100));

  2. 要将第二个矩形定位在 (200, 200),我使用以下命令: drawingContext.PushTransform(new TranslateTransform(100, 100)); drawingContext.DrawRectangle(Brushes.Blue, null, new Rect(0, 0, 100, 100));

  3. 要将第三个矩形定位在 (0, 0),我可以使用 (-200, -200)。 但我很好奇有什么办法可以替换这个累积链并用新位置覆盖整个矩阵 喜欢:drawingContext.PushTransform(new TranslateTransform(0, 0));

这可以在 WinForms 图形上通过如下设置 Transform 属性来实现:

g.Transform = new Matrix();

有什么方法可以打破 WPF 中的累积链

【问题讨论】:

    标签: c# wpf wpf-controls


    【解决方案1】:

    你可以这样做:

    drawingContext.PushTransform(new TranslateTransform(100, 100));      
    drawingContext.DrawRectangle(Brushes.Blue, null, new Rect(0, 0, 100, 100));
    drawingContext.Pop();
    

    Pop() 方法将转换重置为调用 PushTransform() 之前的状态。

    【讨论】:

    • Pop() 是一种可能的选择。但我需要知道单次分配是否有可能打破整个链条。在这个特定的例子中,我需要调用 Pop() 两次。
    【解决方案2】:

    一种可能的解决方法是多次调用 Pop()。但是因为 Pop() 不仅会弹出转换,还会弹出最后一个不透明蒙版、不透明度、剪辑等,它不适合我的需要。

    我刚刚制定的其他可能的解决方案是单独维护额外的 Matrix state 对象。

    每当我们将任何转换推送到 DrawingContext 对象上时,我们还需要将该对象添加到此 state 对象上。

    最后,当我们想要完全打破这条链时,我们可以反转 state 矩阵的状态并将其推送到 DrawingContext 对象上。这会将转换状态设置为 DrawingContext 对象上的单位矩阵。

        //Keep a state matrix
        Matrix state = new Matrix();
    
        //First transform
        MatrixTransform transform1 = new MatrixTransform();
        Matrix matrix1 = new Matrix();
        matrix1.OffsetX = 100;
        matrix1.OffsetY = 100;           
        transform1.Matrix = matrix1;
    
        drawingContext.PushTransform(transform1);
        state.Prepend(matrix1);
        drawingContext.DrawRectangle(..);
    
        //Second transform
        MatrixTransform transform2 = new MatrixTransform();
        Matrix matrix2 = new Matrix();
        matrix2.OffsetX = 400;
        matrix2.OffsetY = 400;           
        transform2.Matrix = matrix2;
    
        drawingContext.PushTransform(transform2);
        state.Prepend(matrix2);
        drawingContext.DrawRectangle(..);
    
    
        //Finally reset to identity matrix.
    
        //Inverse the state matrix
        state.Invert(); 
        //Apply this inverted matrix to DrawingContext to get identity matrix.
        MatrixTransform transform3 = new MatrixTransform();
        transform3.Matrix = state;
        drawingContext.PushTransform(transform3);
        drawingContext.DrawRectangle(...);
    

    【讨论】:

      猜你喜欢
      • 2012-05-22
      • 2020-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-28
      • 1970-01-01
      • 2018-09-20
      • 2020-09-23
      相关资源
      最近更新 更多