【问题标题】:DrawingVisual not showing in WPF Canvas inside a WindowDrawingVisual 未显示在窗口内的 WPF 画布中
【发布时间】:2023-03-16 03:46:01
【问题描述】:

我创建了一个最小的项目,以便“开始”在 WPF 中使用 DrawingVisuals 进行绘图(到目前为止还很初学者)。

我的项目仅包含主窗口的 XAML 和代码。这个项目的唯一目的是打开一个窗口并显示一些填充可用空间的“信号噪声”。

MainWindow.xaml 是这样的:

<Window x:Class="MinimalPlotter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MinimalPlotter"
        Title="MainWindow" Width="1200" Height="800"
        WindowStartupLocation="CenterScreen">

        <Canvas Height="500" Width="700" x:Name="drawingArea" Margin="50" Background="Gray">
            <local:VisualHost Canvas.Top="0" Canvas.Left="0" x:Name="host" Width="700" Height="500" />
        </Canvas>
</Window>

后面的代码是这样的:

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

    public class VisualHost : FrameworkElement
    {

        public VisualHost()
        {
            int h = (int)this.Height;
            int w = (int)this.Width;

            Random random = new Random();
            double r;

            DrawingVisual path = new DrawingVisual();

            StreamGeometry g = new StreamGeometry();
            StreamGeometryContext cr = g.Open();
            cr.BeginFigure(new Point(0,0), false, false);
            for (int i = 0; i < w; i++)
            {
                // ugly calculations below to get the signal centered in container
                r = (random.NextDouble()-0.5) * h -h/2;
                cr.LineTo(new Point(i, r), true, false);
            }
            cr.Close();
            g.Freeze();

            DrawingContext crx = path.RenderOpen();
            Pen p = new Pen(Brushes.Black, 2);
            crx.DrawGeometry(null, p, g);

            // Ellipse included for "visual debugging"
            crx.DrawEllipse(Brushes.Red, p, new Point(50,50), 45, 20);

            crx.Close();

            this.AddVisualChild(path);
        }
    }
}

问题是:当窗口打开时,画布显示在中心,正如预期的那样(带有灰色背景),但没有绘制任何信号。此代码的先前版本使用 Path 几何体可以正常工作,但使用 DrawingVisual 时不显示几何体(甚至不包括用于调试的椭圆几何体)。

感谢阅读!

【问题讨论】:

    标签: wpf drawingvisual


    【解决方案1】:

    您的 VisualHost 类还必须覆盖 VisualChildrenCount 属性和 GetVisualChild 方法:

    public class VisualHost : FrameworkElement
    {
        private DrawingVisual path = new DrawingVisual();
    
        public VisualHost()
        {
            ...
            AddVisualChild(path);
        }
    
        protected override int VisualChildrenCount
        {
            get { return 1; }
        }
    
        protected override Visual GetVisualChild(int index)
        {
            return path;
        }
    }
    

    另请注意,在 using 语句中使用 IDisposable 对象(如 StreamGeometryContext 和 DrawingContext)被认为是一种好的做法:

    var g = new StreamGeometry();
    using (var cr = g.Open())
    {
        cr.BeginFigure(new Point(0,0), false, false);
        ...
        // no need for cr.Close()
    }
    
    using (var crx = path.RenderOpen())
    {
        var p = new Pen(Brushes.Black, 2);
        crx.DrawGeometry(null, p, g);
        crx.DrawEllipse(Brushes.Red, p, new Point(50,50), 45, 20);
        // no need for crx.Close()
    }
    

    【讨论】:

    • 那行得通。我必须弄清楚为什么会这样,但我记得一些教程提到了这些覆盖。谢谢!
    • 所有细节都在MSDN的Using DrawingVisual Objects文章中。
    猜你喜欢
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多