我一直想知道如何使用DrawingContext
相对于不是控件左上角的东西在WPF中绘制内容。我的问题是我想通过连接各种点来绘制一些形状,这些点必须相对于主控件的中心定位,Y指向上方。
我的元素使用自定义DrawingVisual
子类树呈现,其中根是包含Border
的{{1}}子类。我通过将VisualCollection
指定为ScaleTransform
的{{1}}来解决Y方向问题,基本上是垂直翻转整个控件。
答案 0 :(得分:1)
您可以使用在y方向上按-1缩放的MatrixTransform而不是ScaleTransform,并将坐标原点转换为控件的中心。但是,只要控件的大小发生变化,就必须更新此转换。因此,您将覆盖OnRenderSizeChanged,如下所示(假设您设置了控件的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定义为类成员,并将其应用于可视子集合中的每个Visual。
private MatrixTransform transform = new MatrixTransform();
分配给每个新Visual的Transform属性:
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);
}
当然,您只需要将“变换”应用于“顶级”视觉效果。这些视觉的孩子将通过父母的变换而改变。我不完全理解你如何通过“包含VisualCollection的Border子类”来管理你的视觉效果。典型的方法是将一个父ContainerVisual作为可视树的根。然后,变换将仅应用于此根视觉。
答案 1 :(得分:0)
您是否尝试过TranslateTransform?
答案 2 :(得分:0)
好吧,我明白了。我就是这样做的。
首先,我在GroupTransform
子类上定义了WorldTransform
并分配了Border
属性。
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
的反转。
瞧。这可能不是最好的方法,但似乎工作得很好。我没有非常高的性能需求,所以它可能会完成这项工作。