views:

254

answers:

0

Is there a way to decompose a MatrixTransform in WPF in order to remove certain transformations?

I'm rendering an adorner on an item which is the child of a ViewBox. For testing purposes the adorner draws a box around the item.

Let's say I draw the following:

protected override void OnRender(DrawingContext drawingContext)
{
    Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
    Pen renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);          
    drawingContext.DrawLine(renderPen, adornedElementRect.BottomLeft, adornedElementRect.TopLeft);
}

If I don't do anything the line will be transformed as a result of being inside the ViewBox. If however I overwrite the OnRender method like this:

public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
{
    var mt = transform as MatrixTransform;
    var matrix = new Matrix(1, mt.Matrix.M12, mt.Matrix.M21, mt.Matrix.M22, mt.Matrix.OffsetX, mt.Matrix.OffsetY);
    var newTransform = new MatrixTransform(matrix);

    return base.GetDesiredTransform(newTransform);
}

The width of the line remains static and only the length transforms with the ViewBox. This is exactly what I want, but it only works for the line on the left side. I have a nother adorner for the line at the top.

The real problem is for the line at the right side and the bottom:

public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
{
    var mt = transform as MatrixTransform;

    var matrix = new Matrix(1, mt.Matrix.M12, mt.Matrix.M21, mt.Matrix.M22, mt.Matrix.OffsetX, mt.Matrix.OffsetY);
    var newTransform = new MatrixTransform(matrix);

    return base.GetDesiredTransform(newTransform);
}

While this keeps the line width constant, the horizontal position is incorrect and remains static. Instead of being drawn at the right side of the item it's drawn somewhere 3/4 from the left side of the item.

Is there a way to calculate the correct values or to decompose the MatrixTransform into a collection of ScaleTransforms which I can use to build a new MatrixTransform ?

I hope this is not to vague

Update: I could solve the problem with something like this, but it's far from clean or performant... there must be a better way:

var grid = AdornedElement as Grid;
            var viewBox = grid.Parent as Viewbox;            
            var scaleX = viewBox.ActualWidth / grid.ActualWidth;
            var topPoint = new Point(adornedElementRect.Right * scaleX, adornedElementRect.Top);
            var bottomPoint = new Point(adornedElementRect.Right * scaleX, adornedElementRect.Bottom);