2014-03-27 47 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