Search code examples
c#wpfoxyplot

Draw on OxyPlot wpf


I have problem with point's drawing. When I am starting drawing line on the oxyplot canvas nothing happens. But when i am starting beyond the boundaries of oxyplot it works. Why it working so strange? How to resolve this?

<Window x:Class="WpfApplication18DrawProblem.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:oxy="http://oxyplot.org/wpf"
    xmlns:lib="clr-namespace:DrawToolsLib;assembly=DrawToolsLib"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Canvas  Name="paintSurface" MouseDown="Canvas_MouseDown_1" MouseMove="Canvas_MouseMove_1" Grid.Column="1" Background="Transparent">
    </Canvas>
    <oxy:Plot Model="{Binding PlotModel}" Controller="{Binding PlotController}" Height="300" Width="300" Background="Transparent" Grid.Column="0"></oxy:Plot>
</Grid>

using OxyPlot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using DrawToolsLib;
namespace WpfApplication18DrawProblem
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
/// 
public class TestData
{
    public PlotModel PlotModel { get; set; }
    private OxyPlot.Series.LineSeries LS;
    public PlotController PlotController { get; set; }
    public TestData()
    {
        PlotController = new OxyPlot.PlotController();
        PlotController.UnbindAll();
        Random rnd = new Random();
        PlotModel = new PlotModel();
        LS = new OxyPlot.Series.LineSeries();
        for (int i = 0; i < 10; i++)
        {
            LS.Points.Add(new DataPoint(i, rnd.NextDouble()));
        }
        PlotModel.Series.Add(LS);
    }
    public void Update()
    {
        PlotModel.InvalidatePlot(true);
    }
}
public partial class MainWindow : Window
{
    Point currentPoint = new Point();
    TestData TD = new TestData();
    public MainWindow()
    {

        DataContext = TD;
        InitializeComponent();
    }
    private void Canvas_MouseDown_1(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        if (e.ButtonState == MouseButtonState.Pressed)
            currentPoint = e.GetPosition(this);
    }

    private void Canvas_MouseMove_1(object sender, System.Windows.Input.MouseEventArgs e)
    {

        if (e.LeftButton == MouseButtonState.Pressed)
        {
            Line line = new Line();
            Ellipse Ell = new Ellipse()
            {
                Stroke = Brushes.Black,
                StrokeThickness = 2,
            };

            line.Stroke = SystemColors.WindowFrameBrush;
            line.X1 = currentPoint.X;
            line.Y1 = currentPoint.Y;
            line.X2 = e.GetPosition(this).X;
            line.Y2 = e.GetPosition(this).Y;

            currentPoint = e.GetPosition(this);

            paintSurface.Children.Add(line);
        }
        TD.Update();

    }
}
}

enter image description here


Solution

  • The order of the elements in the XAML file plays a role here. If you place the plot area after/on top of the Canvas area, that part of the Canvas will be hidden for user input.

    The most straightforward solution in this case is thus to switch the order of the oxy:Plot and Canvas elements in the XAML file:

    ...
    <Grid>
      <oxy:Plot Model="{Binding PlotModel}" Controller="{Binding PlotController}" Height="300" Width="300" Background="Transparent" Grid.Column="0" />
      <Canvas Name="paintSurface" MouseDown="Canvas_MouseDown_1" MouseMove="Canvas_MouseMove_1" Grid.Column="1" Background="Transparent" />
    </Grid>