3

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

問題は、ウィンドウが開いたときにキャンバスが期待どおりに中央に表示される (灰色の背景) が、信号がプロットされないことです。このコードの以前のバージョンはパス ジオメトリを使用して正常に動作しましたが、DrawingVisual ではジオメトリが表示されません (デバッグ用に含まれる楕円ジオメトリでさえありません)。

読んでくれてありがとう!

4

1 に答える 1

6

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また、ステートメントで StreamGeometryContext や DrawingContext などの IDisposable オブジェクトを使用することをお勧めします。

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()
}
于 2013-01-25T19:35:36.623 に答える