DrawingVisual not showing in WPF Canvas inside window

I created a minimal project to "get started" drawing with DrawingVisuals in WPF (very newbie yet).

My project contains only XAML and code for the main window. The sole purpose of this project is to open a window and display some "signal noise" filling the available space.

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>

      

And the code behind:

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);
        }
    }
}

      

The problem is this: when the window opens, the canvas appears in the center as expected (with a gray background), but no signal will be drawn. The previous version of this code worked fine using path geometry, but no geometry is displayed with the DrawingVisual (not even ellipse geometry included for debugging).

Thanks for reading!

+3


source to share


1 answer


Your VisualHost class will also need to override the VisualChildrenCount property , and 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;
    }
}

      




Note also that it is considered good practice to use IDisposable objects such as StreamGeometryContext and DrawingContext in operations using

:

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()
}

      

+6


source







All Articles