Search code examples
c#wpflinelines

Best practice for showing a lot of lines on grid


I have a program that reads a file and creates about 1000 points (X,Y coordinate) from the files content. I want to display these points as small crosses on a grid (basically a kind of chart).

this is how it should look like (the green and blue crosses) This is what I want

Currently I am doing this in code behind:

foreach (var measurement in collection)
{
  createValueCross(measurement);
}

private void createValueCross(CGM_Measurement measurement)
{
    // set color of line (green when within opt range)
    var crossColor = measurement.Value < mvm.OptMaximum && measurement.Value > mvm.OptMinimum ? Colors.Green : Colors.Blue;

    //create lines
    Line horizontal = new Line();
    Line vertical = new Line();
    vertical.Stroke = horizontal.Stroke = new SolidColorBrush(crossColor);
    vertical.StrokeThickness = horizontal.StrokeThickness = 1;

    //get center coordinates
    var x = measurement.Time.getXPosition();
    x = x < 10 ? 10 : x;
    var y = measurement.Value.getYPosition();
    y = y < 10 ? 10 : y;

    // set line start/endpoint +-2 pix from center 
    horizontal.X1 = x - 2;
    horizontal.X2 = x + 2;
    horizontal.Y1 = horizontal.Y2 = y;
    vertical.Y1 = y - 2;
    vertical.Y2 = y + 2;
    vertical.X1 = vertical.X2 = x;

    // draw lines on grid
    chartDataGrid.Children.Add(horizontal);
    chartDataGrid.Children.Add(vertical);

}

Is there a good way to this in XAML as well? Like in "Polyline" where you can specify a point collection?


Solution

  • So, here is the solution:

    C# Code:

        LinesVM vm;
        public MainWindow()
        {
            InitializeComponent();
    
            vm = new LinesVM();
            vm.Lines = new ObservableCollection<test1.MainWindow.LinePoints>();
            SolidColorBrush col = new SolidColorBrush(Colors.Red);
            vm.Lines.Add(new LinePoints(1, 5, col));
            vm.Lines.Add(new LinePoints(10, 15, col));
            vm.Lines.Add(new LinePoints(41, 45, col));
            vm.Lines.Add(new LinePoints(71, 85, col));
    
            DataContext = vm;
    
    
        }
    
        public class LinesVM
        {
            private ObservableCollection<LinePoints> _lines;
            public ObservableCollection<LinePoints> Lines
            {
                get { return _lines; }
                set
                {
                    if (_lines == value)
                        return;
                    _lines = value;
                }
            }
    
        }
    
        public class LinePoints:INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
    
            public LinePoints(double x, double y, SolidColorBrush color)
            {
                X = x;
                Y = y;
                Color = color;
            }
    
            private SolidColorBrush _color;
            public SolidColorBrush Color
            {
                get { return _color; }
                set
                {
                    if (_color == value)
                        return;
                    _color = value;
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(Color)));
                }
            }
    
            private double _x1;
            public double X1
            {
                get { return _x1; }
                set
                {
                    if (_x1 == value)
                        return;
                    _x1 = value;
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(X1)));
                }
            }
    
            private double _x2;
            public double X2
            {
                get { return _x2; }
                set
                {
                    if (_x2 == value)
                        return;
                    _x2 = value;
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(X2)));
                }
            }
    
            private double _y1;
            public double Y1
            {
                get { return _y1; }
                set
                {
                    if (_y1 == value)
                        return;
                    _y1 = value;
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(Y1)));
                }
            }
    
            private double _y2;
            public double Y2
            {
                get { return _y2; }
                set
                {
                    if (_y2 == value)
                        return;
                    _y2 = value;
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(Y2)));
                }
            }
    
            private double _y;
            public double Y
            {
                get { return _y; }
                set
                {
                    if (_y == value)
                        return;
                    _y = value;                    
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(Y)));
                    Y1 = Y - 2;
                    Y2 = Y + 2;
                }
            }
    
            private double _x;
            public double X
            {
                get { return _x; }
                set
                {
                    if (_x == value)
                        return;
                    _x = value;                    
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(X)));
                    X1 = X - 2;
                    X2 = X + 2;
                }
            }
    
        }
    
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            SolidColorBrush col = new SolidColorBrush(Colors.Black);
            vm.Lines.Add(new LinePoints(21, 25, col));
            vm.Lines.Add(new LinePoints(210, 215, col));
            vm.Lines.Add(new LinePoints(241, 145, col));
            vm.Lines.Add(new LinePoints(171, 185, col));
            vm.Lines[1].Color = col;
        }
    

    and XAML:

     <Grid x:Name="maingrid">
            <Button Height="20" Width="50" HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button_Click_1">click</Button>
    
            <ItemsControl Name="IC" ItemsSource="{Binding Lines}" Margin="10">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
    
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Canvas>
                            <Line Name="horizontal" X1="{Binding X1}" X2="{Binding X2}" Y1="{Binding Y}" Y2="{Binding Y}"
                              StrokeThickness="1" Stroke="{Binding Color}"/>
                            <Line Name="vertical" X1="{Binding X}" X2="{Binding X}" Y1="{Binding Y1}" Y2="{Binding Y2}"
                              StrokeThickness="1" Stroke="{Binding Color}"/>
                        </Canvas>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Grid>