2

我正在尝试创建自己的图形用户控件,我已经在处理 win 表单,并且正在尝试将其移至 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);
    }
}
4

2 回答 2

6

WPF 与 WinForms 非常不同。您没有像 Paint 事件处理程序这样的东西,您经常需要重新绘制无效区域。

在 WPF 中绘制填充整个窗口区域的椭圆的最简单方法是这个 XAML:

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

但当然还有很多其他方法可以达到同样的效果。

如果您需要做更复杂的事情,WPF 提供了大量支持图形和多媒体的类。我建议开始阅读 MSDN 上在线文档的图形部分。


回到您的具体问题,有几件事需要提及。

首先,如果您将 Window 的Background属性设置为Transparent并以非Black.

然后你就会意识到绘制的椭圆比窗口的客户区大。这是因为WidthHeight属性的值包括窗口边框。即使这样,在 WPF 中使用WidthandHeight属性来获取 UI 元素的实际宽度和高度也不是正确的方法,因为这些属性会返回double.NaN,除非它们被显式设置(在 Window 类中除外)。

相反,您通常会使用ActualWidthandActualHeight属性,如在此 UserControl 中(它可能完全符合您的预期):

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);
    }
}
于 2014-03-27T10:22:20.050 回答
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; }
    }
于 2014-03-27T04:40:31.657 回答