我一直想知道如何使用DrawingContext
在WPF中绘制与控件左上角的东西相对的。我的问题是我想通过连接各种点来绘制一些形状,并且这些点必须相对于主机控制的中心,y指向上方。
我的元素是使用自定义DrawingVisual
子类的树呈现的,其中根是包含VisualCollection
的Border
子类。我通过将ScaleTransform
指定为Border
的RenderTransform
来解决Y方向问题,从本质上垂直翻转整个控件。
不过,另一个问题没有这样的运气。有什么想法将我的起源集中?
而不是scaletransform,您可以使用沿y方向缩放-1并将坐标原点转换为控件中心的矩阵transform。但是,每当控件的尺寸变化时,都必须更新此转换。因此,您将覆盖如下所示(假设您设置了控件的 RenderTransform
属性):
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
RenderTransform = new MatrixTransform(1d, 0d, 0d, -1d,
sizeInfo.NewSize.Width / 2d, sizeInfo.NewSize.Height / 2d);
}
编辑:如果您不想转换整个控件,也可以将matrixtransform定义为类成员,并将其应用于视觉儿童集合中的每个视觉效果。
private MatrixTransform transform = new MatrixTransform();
分配到每个新视觉的转换属性:
ContainerVisual visual = ...
visual.Transform = transform;
大小更改,您只需更新该MatrixTransform:
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
transform.Matrix = new Matrix(1d, 0d, 0d, -1d,
sizeInfo.NewSize.Width / 2d, sizeInfo.NewSize.Height / 2d);
}
当然,您只需要将转换应用于"顶级"视觉效果。这些视觉效果的孩子将因父母的转变而改变。我不完全理解您如何通过"包含可录像带的边框子类"管理视觉效果。典型的方法是将一个 parent contuntervisual作为视觉树的根。然后将变换仅应用于此根视觉。
您是否尝试过翻译?
好吧,我明白了。这就是我做的。
首先,我定义了一个GroupTransform
,并分配给Border
子类上的WorldTransform
属性。
var trans = new TranslateTransform();
var conv = new HalfConverter(); // a custom converter that halves whatever you pass to it
BindingOperations.SetBinding(trans, TranslateTransform.XProperty, new Binding { Path = new PropertyPath(ActualWidthProperty), Source = this, Converter = conv });
BindingOperations.SetBinding(trans, TranslateTransform.YProperty, new Binding { Path = new PropertyPath(ActualHeightProperty), Source = this, Converter = conv });
WorldTransform = new TransformGroup();
WorldTransform.Children.Add(new ScaleTransform { ScaleY = -1.0 });
WorldTransform.Children.Add(trans);
VisualTransform = WorldTransform;
然后,当我创建自定义DrawingVisual
的新实例时,我将其Transform
属性分配给我的WorldTransform
。
// ZoneVisual is my DrawingVisual subclass
var vis = new ZoneVisual(zone) { Transform = WorldTransform };
当我添加一个新元素(顺便说一句, Node
)时,我只需要以我的 WorldTransform
的倒数来转换它。
瞧。这可能不是最好的方法,但似乎运行良好。我没有非常高的性能需求,所以它可能会完成工作。