I fail to update a PolyLine for a WorkerThread via a Binding by updating the Source from the Dispatcher. It only works when I update the PolyLine.Points PointCollectionfrom the WorkerThread, but It does not If I bind Polyline.Points to another PointCollection, which then is updated from the WorkerThread. However I get no Exceptions and I can see the Points in both PolyLine.Points and the BindingSource, but the never make it on the screen. When running the code only on the UIThread, the Binding works fine.
It would be nice If someone could explaint that behaviour to me and tell me how to fix this, thank you!
In XAML their is just a Button and a Canvas
public partial class MainWindow : Window
{
PointCollection bindingPoints;
Polyline line;
Dummy dummy;
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
dummy = new Dummy();
dummy.PropertyChanged += dummy_PropertyChanged;
line = new Polyline();
line.Stroke = Brushes.Black;
line.StrokeThickness = 2.0;
this.canvas.Children.Add(line);
bindingPoints = new PointCollection();
Binding bind = new Binding();
bind.Mode = BindingMode.OneWay;
bind.Source = bindingPoints;
//line.SetBinding(Polyline.PointsProperty, bind); //<= If Binding is Set, direct Adding fails
Thread t = new Thread(new ThreadStart(dummy.Move));
t.Start(); //<= Works for direct Adding only
//dummy.Move(); //<= Works for Binding an direct Adding
}
void dummy_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
Dummy d = sender as Dummy;
this.Dispatcher.Invoke((Action)(() =>
{
//line.Points.Add(new Point(d.P.X, d.P.Y)); //<= direct Adding
bindingPoints.Add(new Point(d.P.X, d.P.Y));
}));
}
}
public class Dummy : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Point p;
public Point P
{
get { return p; }
set
{
p = value;
OnPropertyChanged();
}
}
public void Move()
{
Random rnd = new Random();
int i = 0;
do
{
this.P = new Point( i + rnd.Next(1, 10), rnd.Next(i, 250));
Thread.Sleep(rnd.Next(60));
i++;
} while (i < 250);
}
protected void OnPropertyChanged()
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(""));
}
}
}