first of all I describe my objective I want to achive. I want to visualise a continuous data stream (maximum 1000 values per second but could be reduced). This data str
In order to bind the Polyline Points attribute to your viewmodel successfully (i.e. to have it update when the bound PointCollection changes), you should avoid changing the PointCollection as a collection (Clear, Add, etc). The Polyline will not notice that, even binding to an ObservableCollection of Points with a custom converter will not help.
Instead, you should consider your PointCollection as a property: set it with a newly created PointCollection, and fire a NotifyPropertyChanged event:
private PointCollection points = new PointCollection();
public PointCollection Points
{
get { return points; }
set
{
points = value;
NotifyPropertyChanged("Points");
}
}
public void SomeUpdateFunc()
{
PointCollection pc = new PointCollection();
// Do some adding: pc.Add(new Point(x, y)); etc
this.Points = pc; // set via the setter, so the notification will fire
}
Now the Polyline should be updated properly, good luck!
There is at least one possible way to remove grid.DataContext = this;
Add Binding to RelativeSource to the grid itself. In this case the xaml file will looks like
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:WpfApplication2">
<Grid Name="grid" DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:MainWindow, AncestorLevel=1}}">
<Canvas>
<Polyline Points="{Binding Points}" Stroke="Red" StrokeThickness="2" />
</Canvas>
</Grid>
And the code behind will be like this
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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 System.ComponentModel;
namespace WpfApplication2
{
public partial class MainWindow : Window , INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < data.Length; i++)
{
Points.Add(new Point(data[i], data1[i]));
}
NotifyPropertyChanged("Points");
}
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public PointCollection Points { get { return _points; } }
public event PropertyChangedEventHandler PropertyChanged;
private PointCollection _points = new PointCollection();
private short[] data = new short[] { 10, 30, 50, 70, 90, 110, 130, 150, 170, 190, 210 };
private short[] data1 = new short[] { 15, 14, 16, 13, 17, 12, 18, 11, 19, 10, 24 };
}
}
Kai to make the change notification propagate to your bindings you should be making use of a collection which implements change notificaiton, PointCollection
does not do this. You could create your own collection however I'd recommend making use of ObservableCollection<T>
.
In addition here is a similar SO post which also touches on a few other options for making the UI aware of your changes.