2012-03-27 89 views
1

enter image description here如何防止这个布局周期?

图为这些小差距。间隙之间的大蓝容器是宽度被确定的内容持有者。红色边框是可调整大小的持有人

所以两个外面的缝隙描述了左边和右边的填充的红色支架。每个容器旁边的两个间隙是每个容器的左边和右边边距

每当我调整持有者SizeChanged事件会得到提升。

gapsize = (holderWidth - summedUpWidthsOfAllContainers)/numberOfGaps

我通过ActualWidth(的UIElement)属性来获取holderWidth。我重新绑定(Silverlight的黑客)每个容器的MarginProperty和每次我的SizeChanged事件引发的PaddingProperty(UpdateTarget没有在Silverlight中工作,INotifyPropertyChanged不可用)。这在方法中完成,该方法在SizeChanged事件处理程序中调用。

我试图通过比较以前的新边距来防止边缘(小于一个像素)不可见的刷新。

但是用这种方法,我会不时地造成布局周期。现在我只想问是否有逻辑错误。我已阅读this博客,并试图通过这种方式解决它。但是这些布局周期仍然出现。

我这样做是为了在每次持有者获得调整大小时集中内容拥有者(容器)。我知道有两列的电网也是一个可行的解决方案。但问题是,红色持有人必须是一个WrapPanel,在这种情况下,第二个蓝色容器跳过第一个,如果持有人太小,不能显示他们相邻。

+1

很抱歉,如果我误解的东西,但你为什么不只是使用包装面板控制作为你的'红色持有人'? – 2012-03-27 14:59:01

+0

@Dave S:我实际上使用包装面板来达到这个目的。尽管如此,它使得这些柱子彼此粘在一起。这意味着我需要计算这些差距,每当持有者被调整大小以防止这种粘连。 – 2012-03-27 15:06:14

+0

我需要添加一件东西。红色持有者宽度由应用程序的窗口大小确定。正如我们所知,包装面板元素只需使用尽可能多的空间,因为它们需要**。我拉伸了这个包裹面板,但我无法居中水平对齐的元素。这是通过这些差距完成的。 – 2012-03-27 15:14:21

回答

3

在我看来在SizeChanged事件能够最终给你的性能问题的可视化树改变任何原因在于,如果你不小心被调用的多个布局周期(这似乎符合您所描述的问题) 。

如果你需要在一个特定的方式,我会建议创建一个新的面板,并覆盖其布局周期期间使用的ArrangeOverride和方法的MeasureOverride布局的内容。您可以使用现有的WrapPanel源代码(可从Ms-Pl下的CodePlex下载),并根据需要更改逻辑以布置内容。

有很多的文章在网上有关创建自定义面板和Silverlight的布局周期..

对不起,我不能跟你的问题直接帮助,但希望这些信息可以对一些使用到你

+0

是的,你是对的。我意识到我对新旧利润率的检查使它更好。但仍然存在着布局周期。大概你是对的。我要写一个新的面板。谢谢。 – 2012-03-27 15:50:01

1

创建一个可以简单做你想要的面板并不难。下面是给出了空间等量每个孩子一个例子:

using System.Linq; 
using System.Windows; 
using System.Windows.Controls; 

namespace GapPanel 
{ 
    public class GapPanel : Panel 
    { 
     protected override Size MeasureOverride(Size availableSize) 
     { 
      if (Children.Count == 0) 
       return base.MeasureOverride(availableSize); 
      // allot equal space to each child; you may want different logic 
      var spacePerChild = new Size(availableSize.Width/Children.Count, 
             availableSize.Height); 
      foreach (var child in Children) 
       child.Measure(spacePerChild); 
      var totalWidth = Children.Sum(child => child.DesiredSize.Width); 
      var maxHeight = Children.Max(child => child.DesiredSize.Height); 
      return new Size(totalWidth, maxHeight); 
     } 

     protected override Size ArrangeOverride(Size finalSize) 
     { 
      if (Children.Count == 0) 
       return base.ArrangeOverride(finalSize); 
      var gap = (finalSize.Width - Children.Sum(
         child => child.DesiredSize.Width))/(Children.Count + 1); 
      var spacePerChild = (finalSize.Width - gap * (Children.Count + 1)) 
           /Children.Count; 
      for (int i = 0; i < Children.Count; i++) 
      { 
       var child = Children[i]; 
       child.Arrange(new Rect(i * spacePerChild + (i + 1) * gap, 0, 
             spacePerChild, finalSize.Height)); 
      } 
      return finalSize; 
     } 
    } 
} 

你会使用它就像一个普通的面板:

<my:GapPanel> 
    <Button HorizontalAlignment="Center" Width="200" Height="200">abc!</Button> 
    <Button HorizontalAlignment="Center" Width="200" Height="200">foo!</Button> 
    <Button HorizontalAlignment="Center" Width="100" Height="200">bar!</Button> 
</my:GapPanel> 
+0

非常感谢这个。这对我真正需要的小组是一个很好的帮助和基础。 – 2012-03-29 07:02:06