WPF - 绑定和调度程序

时间:2014-04-01 16:52:15

标签: wpf binding dispatcher

我无法通过更新来自Dispatcher的Source来通过Binding更新WorkerThread的PolyLine。它仅在我从WorkerThread更新PolyLine.Points PointCollection时有效,但它没有。如果我将Polyline.Points绑定到另一个PointCollection,然后从WorkerThread更新。 但是我没有Exceptions,我可以看到PolyLine.Points和BindingSource中的Points,但是从来没有在屏幕上显示它。 仅在UIThread上运行代码时,Binding工作正常。

如果有人可以向我解释这种行为并告诉我如何解决这个问题,那就太好了, 谢谢!

在XAML中,它们只是一个Button和一个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(""));
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您只能绑定到属性,将其更改为属性:

PointCollection bindingPoints;