2014-02-18 71 views
5

這可能是一個相當長的涉及到的問題。讓我先說我正在用C#和XAML進行開發。我想創建堆棧以下模板控制:爲Windows Phone 8創建兩列垂直堆棧列控件

_____________ 
|   | 
| Text  | 
| Image  | 
| More Text | 
|___________| 

的項目序列,在兩列,就像這樣:

______ ______ 
| | | | 
| 1 | | 2 | 
|____| | | 
| | |____| 
| 3 | | | 
| | | 4 | 
| | |____| 
|____| | | 
| | | 5 | 
| 6 | | | 
| | 

注意,它們是由高度的第一排序,然後離開向右。

這是相對簡單的作爲一個雙列網格與垂直堆棧面板在每個。

對我來說,這是一個項目序列的表示形式,所以將它作爲一個從ItemsControl繼承的控件進行渲染是有意義的。

我該怎麼做呢?設置一個ItemTemplate似乎很明顯,其他所有內容都會讓我感覺不到。

+0

所以,如果我理解正確的話,你要非常相似畫布面板的東西嗎? –

+0

「包裝面板」的文檔狀態爲:「默認情況下,包裝面板中的元素是從左到右,從上到下水平放置的,但您也可以從上到下垂直放置它們, -to-權「。我的情況是,如果有意義的話,元素需要從上到下,從左到右水平放置。我相信一個包裹面板不會把第五個元素放在原來的位置,而是會轉到下一行。 真的,我不關心算法,我可以弄清楚,我只是想能夠在ItemsControl中手動佈局項目。 – overgroove

+0

是的,它不會把它放在那裏,我只是想澄清:) –

回答

2

我想我們應該使用ListBox並更改ListBox的。我們將一個面板定製爲ItemsPanel,定義並覆蓋方法MeasureOverrideArrangeOverride

代碼位於如下:

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

namespace TravelHelper_WP8 
{ 
    public class CustomPanel : Panel 
    { 
     public CustomPanel() 
     { 
      /**default 2 columns**/ 
      ColumnCount = 2; 
      columnHeight = new double[ColumnCount]; 
      this.UseLayoutRounding = true; 
     } 

     static double[] columnHeight; 

     public int ColumnCount 
     { 
      get { return (int)this.GetValue(ColumnCountProperty); } 
      set { this.SetValue(ColumnCountProperty, value); } 
     } 

     public static DependencyProperty ColumnCountProperty = DependencyProperty.Register("ColumnCount", typeof(int), typeof(CustomPanel), new PropertyMetadata(new PropertyChangedCallback((o, e) => 
     { 
      columnHeight = new double[(int)e.NewValue]; 
      if (o == null || e.NewValue == e.OldValue) 
       return; 
      o.SetValue(ColumnCountProperty, e.NewValue); 
     }))); 

     protected override Size MeasureOverride(Size availableSize) 
     { 
      int indexY = this.Children.Count/ColumnCount; 
      if (this.Children.Count % ColumnCount > 0) indexY++; 
      int flagY = 0; 
      Size resultSize = new Size(0, 0); 
      #region<---- Measure Value 

      for (int i = 0; i < indexY; i++)//Column 
      { 
       if (i == indexY - 1) 
       { 
        int residual = Children.Count - i * ColumnCount; 
        if (Children.Count <= ColumnCount) 
        { 
         residual = Children.Count; 
        } 

        for (int h = 0; h < residual; h++) 
        { 
         Children[ColumnCount * flagY + h].Measure(availableSize); 
         resultSize.Width = (Children[ColumnCount * flagY + h].DesiredSize.Width) * ColumnCount; 
         columnHeight[h] += Children[ColumnCount * flagY + h].DesiredSize.Height; 
        } 
       } 
       else 
       { 
        for (int y = 0; y < ColumnCount; y++) 
        { 
         Children[ColumnCount * flagY + y].Measure(availableSize); 
         resultSize.Width = (Children[ColumnCount * flagY + y].DesiredSize.Width) * ColumnCount; 
         columnHeight[y] += Children[ColumnCount * flagY + y].DesiredSize.Height; 
        } 
        flagY++; 
       } 
      } 
      #endregion 

      resultSize.Height = columnHeight.Max(); 
      return resultSize; 
     } 

     protected override Size ArrangeOverride(Size finalSize) 
     { 
      for (int i = 0; i < columnHeight.Count(); i++) 
      { 
       columnHeight[i] = 0; 
      } 
      int indexY = this.Children.Count/ColumnCount; 
      if (this.Children.Count % ColumnCount > 0) indexY++; 
      int flagY = 0; 
      double flagX = 0; 

      #region<------Layout 
      for (int i = 0; i < indexY; i++)//Column 
      { 
       finalSize.Width = (Children[i].DesiredSize.Width) * ColumnCount; 
       if (i == indexY - 1) 
       { 
        flagX = 0; 
        int residual = Children.Count - i * ColumnCount; 
        if (Children.Count <= ColumnCount) 
        { 
         residual = Children.Count; 
        } 
        for (int h = 0; h < residual; h++) 
        { 
         Children[ColumnCount * i + h].Arrange(new Rect(new Point(flagX, columnHeight[h]), Children[ColumnCount * i + h].DesiredSize)); 
         columnHeight[h] += Children[ColumnCount * flagY + h].DesiredSize.Height; 
         flagX += Children[ColumnCount * i + h].DesiredSize.Width; 
        } 
       } 
       else 
       { 
        for (int y = 0; y < ColumnCount; y++) 
        { 
         Children[ColumnCount * flagY + y].Arrange(new Rect(new Point(flagX, columnHeight[y]), Children[ColumnCount * i + y].DesiredSize)); 
         columnHeight[y] += Children[ColumnCount * flagY + y].DesiredSize.Height; 
         flagX += Children[ColumnCount * flagY + y].DesiredSize.Width; 
        } 
        flagX = 0; flagY++; 
       } 
      } 

      #endregion 

      return finalSize; 
     } 
    } 
} 
+0

雖然我不得不改變安排和測量算法,這正是我需要幫助我到達終點線。謝謝。 – overgroove

+0

不客氣。我很樂意幫助你。 –