WPF多边形绑定后,图形保持不变

时间:2019-05-08 04:57:53

标签: wpf

我以前直接分配给点集,可以正确显示图形,后来发现这样做的性能很差,我想到了使用绑定方法来做。

WPF多边形绑定后,点集已更改,但图形未更改。

xaml代码

<Canvas Background="Black" Name="map">
            <Polygon Name="pl" Points="{Binding sendPoints,Mode=TwoWay}"></Polygon>
        </Canvas>

后端代码


     DrawLinesClass drawLinesClass = new DrawLinesClass();
     pl.DataContext = drawLinesClass;//bind
     pl.Stroke = Brushes.Red;
     pl.StrokeThickness = 2;

 Thread td = new Thread(() =>
            {
                double index = 0,sum=0;
                while (true)
                {
                    Thread.Sleep(50);
                    if (isRun)
                    {
                        sum+=0.01;
                        pl.Dispatcher.Invoke(new Action(() =>
                        {
                            if (sum * 2 >= map.ActualHeight - 40)
                            {
                                sum = 0;
                                index += 1;
                                //drawLinesClass.sendPoints.Clear();
                            }
                            drawLinesClass.sendPoints.Add(new Point(index * sum, sum * 2));

                            //pl.Points = drawLinesClass.sendPoints;//no bind

                        }));
                    }
                }
            });
            td.IsBackground = true;
            td.Start();


绑定模型

 public class DrawLinesClass : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private PointCollection _sendPointsList;

        public PointCollection sendPoints
        {
            get
            {
                if (_sendPointsList == null) _sendPointsList = new PointCollection();
                return _sendPointsList;
            }
            set
            {
                //this._sendPointsList = new PointCollection();
                this._sendPointsList = value;
                OnPropertyChanged("sendPoints");
            }
        }
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

    }

现在绑定点集已更改,我希望图形可以自动更改。

1 个答案:

答案 0 :(得分:0)

绑定

Points="{Binding sendPoints}"

where(Mode=TwoWay是毫无意义的)仅在为其源属性Points分配新值时才更新其目标属性sendPoints。只需像在

中那样将点添加到现有的sendPoints集合中
drawLinesClass.sendPoints.Add(new Point(index * sum, sum * 2));

不会进行绑定更新。

在其他情况下,例如绑定ItemsControl的ItemsSource属性,您只需将ObservableCollection用作source属性。但是,这在这里不起作用。每当添加点时,您实际上都必须创建一个新的PointCollection


除此之外,最好使用DispatcherTimerThread来代替SleepDispatcher.Invoke

double index = 0,sum=0;

var timer = new DispatcherTimer
{
    Interval = TimeSpan.FromMilliseconds(50)
};
timer.Tick += (s, e) =>
{
    sum += 0.01;
    if (sum * 2 >= map.ActualHeight - 40)
    {
        sum = 0;
        index += 1;
    }
    var points = new PointCollection(drawLinesClass.sendPoints);
    points.Add(new Point(index * sum, sum * 2));
    drawLinesClass.sendPoints = points;
};
timer.Start();

要停止计时器,只需致电

timer.Stop();

也最好写

private void OnPropertyChanged(string propertyName)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

最后,您的视图中的绑定通常应使用公共视图模型,因此应使用在DataContext实例处分配的公共MainWindow。当您在诸如like

后面的代码中显式设置折线的DataContext
pl.DataContext = drawLinesClass;

可疑的是,为什么您会完全绑定Polylines的Points属性。除了绑定和设置DataContext外,您还可以直接编写

pl.Points = drawLinesClass.sendPoints;

,从而甚至避免了实现INotifyPropertyChanged的需要。您还可以避免每次更新都需要创建新的PointsCollection,因为

drawLinesClass.sendPoints.Add(new Point(index * sum, sum * 2))

现在可以神奇地工作了。