2013-08-23 34 views
0

我想繪製一個像網格一樣的圖紙作爲畫布的背景。這個網格與我找到的大多數解釋不同,因爲可以縮放畫布以實現縮放。我想要做的是有一系列網格線,即每10^n個單位。然後,由於變焦,網格線會因爲靠近在一起而逐漸淡出。換句話說,如果n很大,那麼與那個網格相關的線應該比較小的n更深/更重。在WPF中繪製淡入淡出的網格

這在WinForms中很容易實現,我通過覆蓋OnPaint並將線的顏色定義爲到下一個網格線的距離的函數來實現它。相距很遠的線被賦予比線接近的更重的權重。

我還沒有想出如何在WPF中做到這一點。我可以通過根據網格線的間距創建一個具有StrokeThickness的線來獲得此行爲,但這隻適用於StrokeThickness和縮放值的小範圍。如果可以將線條定義爲具有非常重的重量,但仍然是一個小的StrokeThickness,它將會起作用。

即使通過使用OnRender實現自定義控件來做到這一點也很困難,因爲我沒有找到一種可靠的方法來在呈現控件時獲取控件的縮放比例(ScaleTransform是父控件之一,而不是直接父控件的一部分)。

關於如何實現這一目標的任何想法將不勝感激!

回答

2

我解決了這個由不增加電網的畫布,但通過堆疊在包含網格中的另一個控件的頂部帆布:

<Grid> 
    <Canvas x:Name="GridLayer"/> 
    <Canvas x:Name="DrawingLayer" /> 
</Grid> 

當變焦事件發生時,我只是重繪GridLayer。

這讓我只畫出需要的線條,正是我想要的線條,在我的情況下非常重要,因爲我有可能是一個巨大的網格線,我不需要再畫線了/比需要的高。這樣我就節省了很多CPU時間。

另一件需要注意的是我實現了我自己的縮放代碼。我沒有使用RenderTransform或ViewBox,因爲我希望該行保持相同的寬度。我所做的只是跟蹤左上角的座標以支持平移和縮放級別。只要其中一個變化,我重繪畫布。我寫了兩個函數:一個將Canvas上的座標轉換爲圖形座標,另一個將相反。第一種方法允許我將光標座標轉換爲圖形座標,第二種方法將圖形的座標轉換爲可用於在畫布上繪製的點。

未經測試的代碼,並作出了很多假設,繞軸的方向:

Point Graph2Canvas(Point graphPoint) 
{ 
    var canvasPoint = new Point(graphPoint); 
    canvasPoint.X *= zoomLevel; 
    canvasPoint.Y *= zoomLevel; 
    canvasPoint.X -= topLeft.X; 
    canvasPoint.Y -= topLeft.Y; 
    return canvasPoint; 
} 

這可以優化,事實是我創造了更多的功能,對於點的集合做同樣的事情。

附加:

我結束了一個更爲複雜的設置,看起來有點像這樣:

<Grid> 
    <Canvas x:Name="BackgroundLayer"/> 
    <Canvas x:Name="GridLayer"/> 
    <Canvas x:Name="AxisLayer"/> 
    <Canvas x:Name="DrawingLayer" /> 
    <Canvas x:Name="SelectionBoxLayer"/> 
    <Canvas x:Name="CursorLayer"/> 
</Grid> 
+0

感謝您的信息。你能詳細說明你如何繪製GridLayer嗎?我試圖構建我的控件,使其不關心實際縮放比例(放大),並將其作爲父控件的責任。當你繪製GridLayer時,你是否會以某種方式從WPF框架獲取縮放信息,或者只是將縮放/縮放傳遞給相關的繪製代碼? – dsharlet

+0

我添加了一些到我的答案 –