我有一个形状,它根据中心周围的节点(角度和因子)的ObservableCollection绘制一条线。
DefiningGeometry覆盖如下所示:
PolyLineSegment curve = new PolyLineSegment(this.Nodes.Select(NodeToPoint), true);
PolyLineSegment bounds = new PolyLineSegment(
new[] { new Point(0, 0), new Point(0, GeometrySize), new Point(GeometrySize, GeometrySize), new Point(GeometrySize, 0) }, false);
PathFigureCollection figures = new PathFigureCollection(new[]
{
new PathFigure(NodeToPoint(this.Nodes[this.Nodes.Count - 1]), new[] { curve }, false),
new PathFigure(new Point(0, 0), new[] { bounds }, false)
});
return new PathGeometry(figures, FillRule.Nonzero, null);如果节点因子或集合发生更改,我将调用InvalidateVisual。这是一个问题,如果我在一个相互交叉的窗口上有更多这样的形状,如果我频繁地改变因子,处理器负载会弹出25% (在QuadCore ofc上)。
绘制频繁更新的LineSegment集合的正确方法是什么?就是塑造正确的组件来实现这一点。?也许我的方法是完全错误的,但我被困在这里了。
编辑:我将代码更新为以下内容:
protected override Geometry DefiningGeometry { get { return this.curveGeometry ?? EmptyBounds; } }
并将PropertyChangedHandler设置为以下内容
private void NodePropertyChanged(object sender, PropertyChangedEventArgs e)
{
Node node = sender as Node;
if (node != null && this.indexMapping.ContainsKey(node) && this.indexMapping[node] != -1)
{
this.UpdatePoint(node);
}
}
private void UpdatePoint(Node node)
{
if (!this.Dispatcher.CheckAccess())
this.Dispatcher.BeginInvoke(new Action<Node>(UpdatePoint), node);
else
{
this.curve.Points[this.indexMapping[node]] = NodeToPoint(node);
this.InvalidateVisual();
}
}正如注释中所述,如果我不调用InvalidateVisual,代码将无法工作。问题仍然存在,如果我添加了5条曲线,总共1000个节点,如果这些线彼此交叉,并且我更改了单个值,则处理器负载开始增加。
我将查看一些处理器采样并返回报告。
发布于 2013-12-05 21:19:27
不需要在每次数据更改时都创建新的几何图形。下面的简化示例(没有MVVM)显示了仅通过在PathGeometry中更改PolyLineSegment中的点来更新UI:
<Grid Background="Transparent" MouseDown="Grid_MouseDown">
<Path Stroke="Black" StrokeThickness="2">
<Path.Data>
<PathGeometry x:Name="geometry"/>
</Path.Data>
</Path>
</Grid>代码隐藏:
public partial class MainWindow : Window
{
private PolyLineSegment segment;
public MainWindow()
{
InitializeComponent();
segment = new PolyLineSegment();
segment.IsStroked = true;
segment.Points.Add(new Point(100, 100));
segment.Points.Add(new Point(200, 200));
var figure = new PathFigure { StartPoint = new Point(0, 0) };
figure.Segments.Add(segment);
geometry.Figures.Add(figure);
}
private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
{
segment.Points[0] = e.GetPosition((IInputElement)sender);
}
}https://stackoverflow.com/questions/20396044
复制相似问题