2012-10-23 48 views
0

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

我的元素使用自定義DrawingVisual子類的樹來呈現,其根子是包含VisualCollectionBorder子類。我通過指定ScaleTransform作爲BorderRenderTransform解決了Y方向問題,基本上垂直翻轉整個控件。

雖然沒有這樣的運氣。任何想法如何中心我的起源?

回答

0

好吧,我明白了。以下是我如何做到的。

首先,我定義了一個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的逆改造它。

Voila。這可能不是最好的方式,但它似乎工作得很好。我沒有非常高的性能需求,所以它可能會完成這項工作。

1

代替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爲類並將其應用於視覺兒童收藏中的每個視覺。

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作爲可視化樹的根。然後,轉換將僅應用於此根視覺。

+0

這不幸地移動了整個'邊界'控制。 –

+0

看我的編輯。我認爲它比你的解決方案簡單得多。主要的一點是它對所有的Visuals都使用相同的Transform實例。 – Clemens

+0

這正是我的解決方案正在做的,實際上。 –

相關問題