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);