【问题标题】:Draw Ontop Of Image Control In WPF在 WPF 中的图像控件之上绘制
【发布时间】:2015-06-11 11:05:57
【问题描述】:

我正在将一个旧的 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 模式。

所以我的问题是:

  • 使用图像控件是否适合此设置?
  • 我应该如何在 WPF 中重新创建这种类似的设置,我可以根据需要更新图像,然后在其上绘制东西。

我的意图是保持传统的 MVVM 模式,但在加载后仍然能够在图像上绘图。所有的绘图都是从应用程序内部完成的,没有用户对绘图的交互。我基本上是在地图图像上实时绘制带有兴趣点的地图。地图是静态的,不会像 Google 的图块那样分成几块,所以我直接从磁盘加载没有问题。

【问题讨论】:

    标签: c# wpf winforms mvvm


    【解决方案1】:

    在干净的 MVVM 方法中,您可以使用带有 Canvas 的 ItemsControl 作为ItemsPanelItemTemplate 中的路径控件。 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;
    }
    

    【讨论】:

      【解决方案2】:

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

      因此,对于寻找类似解决方法的其他人,我推荐使用画布控件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-24
        • 1970-01-01
        • 2021-03-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多