在WPF中的图像控件上绘制

时间:2015-04-07 00:06:44

标签: c# wpf winforms mvvm

我正在努力将一个旧的WinForms项目移植到WPF,但是已经碰壁了。在这个旧的WinForms项目中,我正在使用一个每秒绘制一个图像的图片控件。除此之外,我还有控件' Paint'事件被覆盖,以便在图像已经设置后在图像上绘制自定义内容。

例如,我的代码流程如下:

private void timer1_Tick(object sender, System.EventArgs e)
{
    pictureBox1.Load("some/image/path");
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    var g = e.Graphics;
    // do custom drawing on top of the picture here..
}

WPF没有提供直接的' Paint'因此我不确定如何将其正确移植到WPF并仍保留MVVM模式。

所以我的问题是:

  • 使用Image控件正确进行此设置吗?
  • 我应该如何在WPF中重新创建这个类似的设置,我可以根据需要更新图像,然后在上面绘制内容。

我的目的是保持传统的MVVM模式,但仍然可以在加载后绘制到图像上。所有绘图都是从应用程序内部完成的,没有用户与绘图的交互。我基本上是在地图图像上实时绘制一个有兴趣点的地图。地图是静态的,不会像Google的瓷砖那样分成碎片,所以我没有直接从磁盘加载的问题。

2 个答案:

答案 0 :(得分:1)

在干净的MVVM方法中,您可以使用带有Canvas的ItemsControl ItemsPanelItemTemplate中的Path控件。 Path控件绑定到一组适当的视图模型属性,这些属性定义了图形的可视外观。

<ItemsControl ItemsSource="{Binding Drawings}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Path Data="{Binding Geometry}"
                  Fill="{Binding Fill}"
                  Stroke="{Binding Stroke}"
                  StrokeThickness="{Binding StrokeThickness}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

视图模型可能是这样的:

public class Drawing
{
    public Geometry Geometry { get; set; }
    public Brush Fill { get; set; }
    public Brush Stroke { get; set; }
    public double StrokeThickness { get; set; }
}

public class ViewModel
{
    public ObservableCollection<Drawing> Drawings { get; set; }
}

可能会使用如下所示。

public MainWindow()
{
    InitializeComponent();

    var vm = new ViewModel();
    vm.Drawings = new ObservableCollection<Drawing>();
    vm.Drawings.Add(new Drawing
        {
            Geometry = new EllipseGeometry(new Point(100, 100), 50, 30),
            Fill = Brushes.LightBlue,
            Stroke = Brushes.Blue,
            StrokeThickness = 2
        });
    vm.Drawings.Add(new Drawing
    {
        Geometry = new RectangleGeometry(new Rect(50, 150, 100, 60)),
        Fill = Brushes.LightGreen,
        Stroke = Brushes.Green,
        StrokeThickness = 2
    });

    DataContext = vm;
}

答案 1 :(得分:0)

好了,经过大量的修修补补,我找到了适合我需要的方法。使用画布控件并将其暴露给我的viewmodel我可以将各种对象绘制到画布上以复制绘图的WinForm样式。

因此,对于其他寻找类似工作的人,我建议使用画布控件。