none
自定义Panel中怎么包含其他panel? RRS feed

  • 问题

  • 比如说,做一个TwoColumnStackPanel。顾名思义,一般的StackPanel只能把子元素叠成一列,而我的TwoColumnStackPanel可以把元素叠成两列。

    TwoColumnStackPanel要把子元素平均地分布在两列上,比如4个子元素,左边2个,右边2个;5个子元素,左边3个,右边2个。

    我想到TwoColumnStackPanel其实是两个并排的StackPanel,所以想能不能用StackPanel来实现我的TwoColumnStackPanel。

        class TwoColumnStackPanel : Panel
        {
            private readonly StackPanel leftPanel;
            private readonly StackPanel rightPanel;
    
            public TwoColumnStackPanel()
            {
                leftPanel = new StackPanel();
                rightPanel = new StackPanel();
            }
    
            protected override Size MeasureOverride(Size availableSize)
            {
                int size = InternalChildren.Count;
                int leftCount = size / 2;
                int rightCount = size - leftCount;
                int index = 0;
                leftPanel.Children.Clear();
                for (int s = 0; s < leftCount; s++)
                {
                    leftPanel.Children.Add(InternalChildren[index + s]);
                }
    
                index += leftCount;
                rightPanel.Children.Clear();
                for (int s = 0; s < rightCount; s++)
                {
                    rightPanel.Children.Add(InternalChildren[index + s]);//指定的元素已经是另一个元素的逻辑子元素。请先将其断开连接。
                }
    
    
                double columnWidth = availableSize.Width / 2;
    
                leftPanel.Measure(new Size(columnWidth, availableSize.Height));
                rightPanel.Measure(new Size(columnWidth, availableSize.Height));
    
                return new Size(leftPanel.DesiredSize.Width + rightPanel.DesiredSize.Width, Math.Max(leftPanel.DesiredSize.Height, rightPanel.DesiredSize.Height));
            }
    
            protected override Size ArrangeOverride(Size finalSize)
            {
                leftPanel.Arrange(new Rect(0,0,leftPanel.DesiredSize.Width,leftPanel.DesiredSize.Height));
                rightPanel.Arrange(new Rect(leftPanel.DesiredSize.Width,0,rightPanel.DesiredSize.Width,rightPanel.DesiredSize.Height));
    
                return finalSize;
            }
        }

    运行的时候会在标记出出错。

    我怀疑我写法不正确。。。怎么改正?

    谢谢大侠

    2012年12月17日 16:18

全部回复

  • 我不建议你使用custompanel去做, 因为custom panel主要是对于布局排列的方式,因为你会重新写“MeasureOverride”和“ArrangeOverride”,比如你要让你的元素排列排列成一个圆或者斜线排列,这个时候我们会用Custom panel去做,但是你描述的我觉得你可以用UniformGrid去做,定义UniformGrid的列数是2,然后就可以排列了。


    Sheldon _Xiao
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2012年12月18日 9:51
    版主
  • 举这个例子是为了写代码方便点。

    我实际上想要一个类似DockPanel和StackPanel结合的效果。

    1个子元素->在上面

    2个子元素->并排在上面(StackPanel.Orientation=Horiontal)

    3个子元素->1个在上面,另外2个分别在左右。

    4个子元素->2个并排在上面,另外2个分别在左右。

    N个子元素->N/3在左边(StackPanel.Orientation=Vertical),N/3在右边,余下的在上面。

    其中上、左、右是这么排的:dock左、dock右,dock上,中间空着。

    如果我可以有这样一个panel,我可以把它用在ListBox里,我把元素放进去后就可以很容易得单选或多选了。


    2012年12月18日 10:22
  • 你这个写法是不正确的, 你这样的写法像是在写一个用户控件.

    自定义Panel 的写法不应该操作视觉树对象, 而是告诉他们怎么布局即可. 也就是仅询问子元素的大小, 然后分配位置就可以了.

    2012年12月26日 9:41