[英]Draw relative to center with DrawingContext
我一直想知道如何在WPF中使用DrawingContext
相對於不在控件左上角的東西進行繪制。 我的問題是我想通過連接各種點來繪制一些形狀,並且這些點必須相對於主機控件的中心定位,Y指向上方。
我的元素是使用自定義DrawingVisual
子類的樹呈現的,其根是包含VisualCollection
的Border
子類。 我通過指定ScaleTransform
作為Border
的RenderTransform
來解決Y方向問題,本質上是垂直翻轉整個控件。
但是,在其他問題上沒有這樣的運氣。 關於如何使我的血統居中的想法嗎?
可以使用MatrixTransform代替ScaleTransform,該MatrixTransform在y方向上按-1縮放並將坐標原點平移到控件的中心。 但是,每當控件大小更改時,都必須更新此轉換。 因此,您將像下面那樣重寫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作為視覺樹的根。 然后,僅將變換應用於此基本視覺效果。
您嘗試過TranslateTransform嗎?
好吧,我明白了。 這是我的方法。
首先,我定義了一個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
的逆來對其進行轉換。
瞧 這可能不是最好的方法,但似乎效果很好。 我對高性能的需求不高,因此它可能會勝任。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.