2014-03-27 102 views
2

我想創建自己的圖形用戶控件,我有一個已經在贏取窗體上工作,並且我試圖將它移入WPF世界。我開始學習如何繪圖,所以首先我想繪製一個填充整個窗口的黑色橢圓,只是爲了學習如何在WPF中使用座標。試圖在WPF窗口中繪製橢圓,但它不可見

所以這裏是代碼,當我運行應用程序時,什麼都不顯示,任何想法我錯過了什麼?

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnRender(DrawingContext drawingContext) 
    { 
     base.OnRender(drawingContext); 

     drawingContext.DrawEllipse(Brushes.Black, new Pen(Brushes.Black, 1), new Point(Width/2, Height/2), Width/2, Height/2); 
    } 
} 

回答

6

WPF是的WinForms非常不同。您沒有像Paint事件處理程序那樣的東西,您不斷需要重新繪製無效區域。

的easist方式繪製填充在WPF整個窗口區域的橢圓是這個XAML:

<Window ...> 
    <Grid> 
     <Ellipse Stroke="Black" Fill="Black"/> 
    </Grid> 
</Window> 

當然的,但也有很多其他的方法來達到同樣的效果。

如果您需要做更復雜的事情,WPF提供了大量支持圖形和多媒體的類。我建議開始閱讀MSDN上在線文檔的Graphics部分。


要回到您的具體問題,有幾件事情需要提及。

首先,如果您將窗口的Background屬性設置爲Transparent,並且已繪製橢圓的顏色不是Black,您將會看到OnRender覆蓋的結果。

然後你會意識到繪製的橢圓大於窗口的客戶區域。這是因爲WidthHeight屬性的值包括窗口邊框。即使如此,使用WidthHeight屬性來獲取WPF中UI元素的實際寬度和高度並不是正確的方法,因爲除非它們被明確設置(除了在Window類中),否則這些屬性返回double.NaN

相反,你通常會使用ActualWidthActualHeight屬性,如在此用戶控件(這也許是做了你打算什麼):

public partial class DrawingControl : UserControl 
{ 
    public DrawingControl() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnRender(DrawingContext drawingContext) 
    { 
     base.OnRender(drawingContext); 

     drawingContext.DrawEllipse(Brushes.Black, 
      new Pen(Brushes.Black, 1), 
      new Point(ActualWidth/2, ActualHeight/2), 
      ActualWidth/2, ActualHeight/2); 
    } 
} 
+0

感謝您的完整答案 – Bishoy

+0

+1克萊門斯,我有同樣的問題,其中指定一個背景顏色,而不是「透明」模糊了我畫的任何東西。是否可以將背景顏色設置爲其他任何內容而不阻礙繪製的內容?謝謝。 – Sabuncu

+0

@Sabuncu你的意思是你的主窗口中有一個重寫的OnRender方法?總之,你應該不這樣做。如果你真的需要*來覆蓋OnRender,你不應該在一個窗口中,而是在一個自定義控件中。 – Clemens

1

下面是示例我所做的,

public MainWindow() 
    { 
     InitializeComponent(); 

     var canvas = new Canvas(); 
     Content = canvas; 

     var element = new DrawingVisualElement(); 

     canvas.Children.Add(element); 
     CompositionTarget.Rendering += (s, e) => 
     { 

      using (var dc = element.visual.RenderOpen()) 
       dc.DrawEllipse(Brushes.Black, 
       new Pen(Brushes.Blue, 3),  // Border 
       new Point(120, 120), 20, 40); 
     }; 

     Mouse.Capture(canvas); 
     MouseDown += (s, e) => Mouse.Capture((UIElement)s); 
     MouseMove += (s, e) => Title = e.GetPosition(canvas).ToString(); 
     MouseUp += (s, e) => Mouse.Capture(null); 


    } 
    class DrawingVisualElement : FrameworkElement 
    { 
     public DrawingVisual visual; 

     public DrawingVisualElement() { visual = new DrawingVisual(); } 

     protected override int VisualChildrenCount { get { return 1; } } 

     protected override Visual GetVisualChild(int index) { return visual; } 
    } 
+0

感謝sajeetharan,但可以請你解釋一下,從我原來失蹤碼? – Bishoy

+0

您應該將其添加到畫布內 – Sajeetharan

+0

-1此處使用'CompositionTarget.Rendering'事件。這在這裏絕對是不必要的,可能會導致OP進入一個完全錯誤的方向。 – Clemens