首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用DataBinding绘制PolyLine

使用DataBinding绘制PolyLine
EN

Stack Overflow用户
提问于 2013-12-05 17:25:08
回答 1查看 919关注 0票数 1

我有一个形状,它根据中心周围的节点(角度和因子)的ObservableCollection绘制一条线。

DefiningGeometry覆盖如下所示:

代码语言:javascript
复制
            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设置为以下内容

代码语言:javascript
复制
  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个节点,如果这些线彼此交叉,并且我更改了单个值,则处理器负载开始增加。

我将查看一些处理器采样并返回报告。

EN

回答 1

Stack Overflow用户

发布于 2013-12-05 21:19:27

不需要在每次数据更改时都创建新的几何图形。下面的简化示例(没有MVVM)显示了仅通过在PathGeometry中更改PolyLineSegment中的点来更新UI:

代码语言:javascript
复制
<Grid Background="Transparent" MouseDown="Grid_MouseDown">
    <Path Stroke="Black" StrokeThickness="2">
        <Path.Data>
            <PathGeometry x:Name="geometry"/>
        </Path.Data>
    </Path>
</Grid>

代码隐藏:

代码语言:javascript
复制
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);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20396044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档