如何使网格像自定义控件满足这些要求

时间:2012-03-31 12:38:55

标签: c# wpf

我需要一个具有以下功能的控件:

  1. 应该可以在xaml中使用它进行设计。
  2. 它应该能够容纳单个类型的多个子元素。例如说Button
  3. 这些子元素将具有固定的尺寸。控件必须确定它可以完全垂直和水平显示的最大子项数(不能部分显示任何子项)。并且只显示那些孩子但保留不可见的孩子供以后使用。 - 我想我可以使用Grid
  4. 完成此要求
  5. 应该可以为这些子元素设置动画 - 我想这不是问题。
  6. 我尝试编写自定义控件来执行此操作。我从Grid继承并看到Grid实现了IAddChild我认为如果我覆盖AddChild我可以捕获添加的元素。但现在我发现AddChild中的Grid也没有实现!所以我似乎不能这样做。我应该从哪里开始?

    编辑:感谢Alan的指点,我让它发挥作用......

    public class AutoLayoutingPanel : Panel
    {
        protected override Size MeasureOverride(Size availableSize)
        {
            Size size = new Size();
            size.Height = double.MaxValue;
            size.Width = double.MaxValue;
    
            foreach (UIElement child in Children)
            {
                child.Measure(size);
                size.Height += child.DesiredSize.Height;
                size.Width += child.DesiredSize.Width;
            }
    
            return availableSize;
        }
    
        protected override Size ArrangeOverride(Size finalSize)
        {
            ArrangeGrid(finalSize);
            return finalSize;
        }
    
        private void ArrangeGrid(Size finalSize)
        {
            foreach (UIElement child in Children)
            {
                child.Visibility = Visibility.Hidden;
            }
    
            Size maxCellSize = new Size();
    
            foreach (UIElement child in Children)
            {
                maxCellSize.Height = Math.Max(child.DesiredSize.Height, maxCellSize.Height);
                maxCellSize.Width = Math.Max(child.DesiredSize.Width, maxCellSize.Width);
            }
    
            int rowCount = (int)Math.Floor(finalSize.Height / maxCellSize.Height);
            int colCount = (int)Math.Floor(finalSize.Width / maxCellSize.Width);
    
            int row = 0, col = 0;
            foreach (UIElement child in Children)
            {
                if (row < rowCount && col < colCount)
                {
                    Rect pos = new Rect(col * maxCellSize.Width, row * maxCellSize.Height, maxCellSize.Width, maxCellSize.Height);
                    child.Visibility = System.Windows.Visibility.Visible;
                    child.Arrange(pos);
                }
                else
                {
                    break;
                }
    
                if (++row >= rowCount)
                {
                    row = 0;
                    ++col;
                }
            }
        }
    }
    

1 个答案:

答案 0 :(得分:1)

我认为您需要创建自定义布局面板而不是尝试从Grid继承(对于IAddChild接口,它是使用EIMI实现的,因此既不可见也不可覆盖外)。 Here是一个很好的起点。

(另外,你需要考虑如何限制你的控件可以容纳的子控件的类型。使用泛型是一种选择,但我对XAML泛型支持有疑问。)