2012-09-02 52 views
0

我写了一个Windows Forms C#应用程序来绘制像线这样的矢量图元。椭圆等我有一个方法来改变选定图形的边框宽度。这是方法:为什么这种方法工作如此缓慢?

public void SetBorderWidth(int border) 
    { 
     if (border < 0) 
      return; 

     if ((SelectedItem != null) && (SelectedItem.isGroup == false)) 
     {    
      SelectedItem.BorderWidth = border; 
     } 

     if ((SelectedItem != null) && (SelectedItem.isGroup == true)) 
     { 

      ChangeCascadeBorderWidth(SelectedItem, border); 
     } 

     foreach (Shape figure in ObjectsDrawn) 
     { 
      if (figure.Selected) 
      { 
       ObjectsDrawn[ObjectsDrawn.IndexOf(figure)].BorderWidth = border; 
      } 

      if (figure.isGroup) 
      { 
       ChangeCascadeBorderWidth(figure, border); 
      } 
     }    
    } 

谁调用方法:

private void ChangeCascadeBorderWidth(Shape group, int width) 
    { 
     foreach (Shape item in ((Grouping)group).GroupedElements) 
     { 
      if (item.isGroup == true) 
      { 
       ChangeCascadeBorderWidth(item, width); 
      } 
      else 
      { 
       item.BorderWidth = width; 
      } 
     } 
    } 

如果这个数字是几个数字组。但是这个工作太慢了。无论我选择了一组还是一组数字,有时候我都要等10-15秒。用于改变边框宽度。为什么这么慢?

+0

多次暂停调试器。它在哪里停止最多? – usr

+0

当我有一个数字时,它停在这里一次:SelectedItem.BorderWidth = border;有一次在这里:ObjectsDrawn [ObjectsDrawn.IndexOf(figure)]。BorderWidth = border ;. 当我有一组两个数字时,它在这里停止一次:ChangeCascadeBorderWidth(SelectedItem,border);一次在这里:ChangeCascadeBorderWidth(figure,border);;这里有一次:ObjectsDrawn [ObjectsDrawn.IndexOf(figure)]。 BorderWidth = border;这里有四次:item.BorderWidth = width ;. –

+0

现在你知道哪些行很慢!找出为什么。查看调用堆栈以查看线程停止在哪个函数中。我的猜测:IndexOf在一长串名单上。 – usr

回答

0

我的想法:

的一个像素导致更快的性能,因为边框可以使用基于行的基元被渲染的宽度。

当您使用大于1的宽度时,它必须使用固体填充的基元,这将会很慢。

0

您的代码正在编辑SelectedItem的边框,Selected属性设置为true的任何ObjectDrawn以及属于组的所有绘制的所有对象的边框。

您是否也想根据是否选择组形状来过滤组边框图?
figure.isGroup && figure.Selected 否则,它似乎会修改所有组的边界,如果有很多组的边界,可能会导致性能问题,无论您选择了什么。

其他性能改进建议:
您在SetBorderWidth做到这一点:
ObjectsDrawn[ObjectsDrawn.IndexOf(figure)].BorderWidth = border; 但你在ChangeCascadeBorderWidth做到这一点: item.BorderWidth = width; 我建议做同样的事情在SetBorderWidth功能SICE你已经有了对象的实例您希望修改,IndexOf查找似乎不是必需的。此外,如果设置BorderWidth属性的成本很高(即使设置为相同的现有值),然后将您的调用包装为SetBorderWidth,如下所示: if(item.BorderWidth != width) item.BorderWidth = width;可以节省性能。但是您必须评估比较成本与设置边框宽度的成本。

0

您发布的所有瓶颈似乎是通过在您的形状上设置BorderWidth属性。我猜你会重绘或更新BorderWidth中形状的布局。如果你在一个容器上设置BorderWidth,会有很多不必要的重绘和布局更改,这些更改在WinForms中很慢(特别是对于布局,如果你的形状从Control继承)。

我可能会建议一个开始更新 * EndUpdate *机制像其他一些WinForms控件一样吗?

相关问题