簡體   English   中英

使用DrawingContext相對於中心進行繪制

[英]Draw relative to center with DrawingContext

我一直想知道如何在WPF中使用DrawingContext相對於不在控件左上角的東西進行繪制。 我的問題是我想通過連接各種點來繪制一些形狀,並且這些點必須相對於主機控件的中心定位,Y指向上方。

我的元素是使用自定義DrawingVisual子類的樹呈現的,其根是包含VisualCollectionBorder子類。 我通過指定ScaleTransform作為BorderRenderTransform來解決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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM