2011-05-11 216 views
6

所以,我用winForms .CreateGraphics繪製了各種不同的東西,從線到框到圖像。這是非常活潑和迴應。相當於wpf中的CreateGraphics

我想學習WPF在C#

我發現,WPF允許我「添加」矩形物體在畫布將正常顯示。不過,我有時候會畫數十萬個矩形,畫圖速度會變得非常慢,而當我移動矩形中的一個時,UI變得不那麼活潑。

在winForms中直接繪製元素的速度並不是很快,但無論繪製多少,它都是一致的。

是否有類似的解決方案來做這件事在WPF?

我試着添加一個linq到System.Drawing,它給了我一個Graphics對象,但我試過的wpf元素都沒有.CreateGraphics()方法。

+3

聖@#%(.CreateGraphics不存在WPF無論??????每一天我找到新的理由使用WPF作爲一種形式的選擇後悔,這就像使用取勝的形式,並盡一切易如反掌或者使用WPF和gl搜索10個小時如何做一些簡單的事情 – 2012-04-27 13:44:58

回答

2

您需要創建一個覆蓋OnRender的控件,並在那裏進行繪圖。你沒有辦法繪製另一個控件,但控件可以繪製自己。

此外,請記住,WPF使用retained graphics,所以如果您更改了某些內容,則需要根據需要使視覺無效。

編輯:

喜歡的東西:

public class MyControl : Control { 

    public MyControl() { 
     this.Rects = new ObservableCollection<Rect>(); 
     // TODO: attach to CollectionChanged to know when to invalidate visual 
    } 

    public ObservableCollection<Rect> Rects { get; private set; } 

    protected override void OnRender(DrawingContext dc) { 
     SolidColorBrush mySolidColorBrush = new SolidColorBrush(); 
     mySolidColorBrush.Color = Colors.LimeGreen; 
     Pen myPen = new Pen(Brushes.Blue, 10); 

     foreach (Rect rect in this.Rects) 
      dc.DrawRectangle(mySolidColorBrush, myPen, rect); 
    } 
} 
+0

我想出了無效,以及如何強制重繪。如果我有一個名爲'canvas的Canvas對象,你願意提供一個簡短的片段嗎? ',以及如何覆蓋只有該對象的'OnRender()'方法? – ohmusama 2011-05-11 17:57:25

+0

@ohmusama - 無論如何,你不需要使用類似於Canvas的東西。你的控件只會渲染矩形,但實際上並不會有任何UIElement矩形(只是Rect),OnRender鏈接顯示一個示例控件 – CodeNaked 2011-05-11 18:03:26

+0

這是否需要我擴展現有的canvas類以覆蓋它?如果我的新canvas類是'c lass MyCanvas:Canvas' in yaml我會創建一個''而不是''如果我理解了一切正確的話? – ohmusama 2011-05-11 18:13:46

2

正如有人說,WPF使用一個保留圖形的方法讓你真正在內存中創建100000個矩形對象,然後繪製所有的人。減速可能是由於垃圾收集和一般內存問題。

除了重寫OnRender方法,還有一些你可以看看的東西。

  1. 使用GDI方法的熟悉,然後將結果寫入一個WPF WriteableBitmap的

  2. 使用D3DImage並採取硬件加速的優勢繪製矩形到圖像中的後臺線程。這要求您瞭解DirectX(或Direct2D)庫。如果你對這種方法感興趣,我會建議看看SlimDx。

4

WPF使用與WinForms不同的圖形操作模型。

使用WinForms,您可以直接編輯屏幕上的像素。繪製像素後,矩形的概念會丟失。繪製像素是一個非常快速的操作。

使用WPF,您不控制屏幕上的像素。 DirectDraw是。 DirectDraw是一個基於矢量的合成引擎。你不畫像素。您定義矢量形狀(或視覺效果)。即使在圖像呈現在屏幕上之後,形狀或矩形的概念仍爲「保留」。當您添加一個與其他矩形重疊的新矩形時,所有其他矩形都需要進行重新渲染。這可能是您的表現正在放緩的地方。這在使用WinForms時不會發生。

您可以通過覆蓋的OnRender有點改善WPF的性能。您可以剪掉Rectangle對象的開銷並直接提供視覺效果。但是,您仍然沒有在屏幕上繪製像素。您正在定義DirectDraw用於呈現圖像的形狀。在這方面,OnRender名稱可能有點誤導。

我相信你可以找到大量的技巧,以提高在WPF應用程序的性能。還有一些方法仍然可以繪製像素 - 但這有點擊敗了WPF的觀點。

你在做什麼,需要數千個矩形?

+1

製作迷宮:http://imgur.com/a/27PPs#5W1Ou和http:// imgur。 COM/ftFOv – ohmusama 2011-05-11 18:17:03

2

問題是大多數likeley不是WPF無法呈現的圖形對象1000,但您創建和添加項目太遠了WPF對象層次結構。它畢竟使用GPU來處理所有的圖形工作。

只要你開始基於後一個「UIElement」添加對象,你就應該儘可能的把對象添加到「Visual」類中,你要求WPF跟蹤每個對象的用戶點擊,懸停等等,不只是畫出來。

+0

我加入'Rectangle's到'Canvas'這是MainWindow'的'這裏的/你會如何添加這些矩形的孩子。我是用「myCanvas.Add(myRectangle)' – ohmusama 2011-05-11 20:08:52

+0

其實WPF矩形會似乎是一個不錯的選擇;它是框架最低級別的形狀繪製的東西,但是它繼承自FrameworkElement,它已經得到了一些命中測試/鼠標懸停在/ etc的包裝上,您可能想要考慮創建自己的自定義控件(基於Visual如果你能)爲可以去除儘可能多的運行時UI控件行李。 – 2011-05-11 20:48:06

+0

有什麼特別的,我需要做的,使自己的自定義控制繼承視覺,使其可用,或者一個鏈接就足夠了。 – ohmusama 2011-05-11 21:06:39