DrawingVisual не отображается в холсте WPF внутри окна
Я создал минимальный проект, чтобы "начать работу" с рисованием с помощью DrawingVisuals в WPF (пока он был новичком).
Мой проект содержит только 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);
}
}
}
Проблема в том, что когда открывается окно, Canvas отображается в центре, как и ожидалось (с серым фоном), но сигнал не отображается. Предыдущая версия этого кода работала нормально с использованием геометрии Path, но с 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;
}
}
Обратите также внимание, что считается хорошей практикой использовать IDisposable объекты, такие как StreamGeometryContext и DrawingContext, в 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()
}