我以前直接分配给点集,可以正确显示图形,后来发现这样做的性能很差,我想到了使用绑定方法来做。
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));
}
}
现在绑定点集已更改,我希望图形可以自动更改。
答案 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
。
除此之外,最好使用DispatcherTimer
和Thread
来代替Sleep
和Dispatcher.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))
现在可以神奇地工作了。