2012-03-27 88 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