Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何为这些需求创建类似网格的自定义控件_C#_Wpf - Fatal编程技术网

C# 如何为这些需求创建类似网格的自定义控件

C# 如何为这些需求创建类似网格的自定义控件,c#,wpf,C#,Wpf,我需要一个具有以下功能的控件: 应该可以在xaml中使用它进行设计 它应该能够容纳单个类型的多个子元素。例如说按钮 这些子元素将具有固定的尺寸。控件必须计算出它可以完全垂直和水平显示的最大子级数(不能部分显示任何子级)。并且只显示这些子项,但保留不可见的子项供以后使用。-我想我可以通过网格完成这个要求 应该有可能动画这些子元素-我想这不是一个问题 我试图编写一个自定义控件来实现这一点。我继承了一个网格,看到网格实现了IAddChild,我想如果我重写AddChild,我可以捕获添加的元素。但是现

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

  • 应该可以在xaml中使用它进行设计
  • 它应该能够容纳单个类型的多个子元素。例如说
    按钮
  • 这些子元素将具有固定的尺寸。控件必须计算出它可以完全垂直和水平显示的最大子级数(不能部分显示任何子级)。并且只显示这些子项,但保留不可见的子项供以后使用。-我想我可以通过
    网格
    完成这个要求
  • 应该有可能动画这些子元素-我想这不是一个问题
  • 我试图编写一个自定义控件来实现这一点。我继承了一个
    网格
    ,看到
    网格
    实现了
    IAddChild
    ,我想如果我重写
    AddChild
    ,我可以捕获添加的元素。但是现在我发现
    Grid
    中也没有
    AddChild
    的实现!看来我不能那样做。我应该从哪里开始

    编辑:多亏了艾伦的指点,我让它工作了

    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;
                }
            }
        }
    }
    
    公共类自动布局面板:面板
    {
    受保护的覆盖尺寸测量覆盖(尺寸可用尺寸)
    {
    尺寸=新尺寸();
    size.Height=double.MaxValue;
    size.Width=double.MaxValue;
    foreach(UIElement子元素中的子元素)
    {
    儿童。测量(尺寸);
    size.Height+=child.DesiredSize.Height;
    size.Width+=child.DesiredSize.Width;
    }
    返回可用性;
    }
    受保护的替代尺寸排列替代(尺寸最终化)
    {
    安排网格(最终化);
    返回最终化;
    }
    专用void ArrangeGrid(大小最终化)
    {
    foreach(UIElement子元素中的子元素)
    {
    child.Visibility=Visibility.Hidden;
    }
    大小maxCellSize=新大小();
    foreach(UIElement子元素中的子元素)
    {
    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行=0,列=0;
    foreach(UIElement子元素中的子元素)
    {
    if(行<行计数和列<列计数)
    {
    Rect pos=new Rect(列*maxCellSize.Width,行*maxCellSize.Height,maxCellSize.Width,maxCellSize.Height);
    child.Visibility=System.Windows.Visibility.Visible;
    儿童安排(pos);
    }
    其他的
    {
    打破
    }
    如果(++行>=行计数)
    {
    行=0;
    ++上校;
    }
    }
    }
    }
    
    我认为您需要创建一个自定义布局面板,而不是尝试从
    网格继承
    (至于
    IAddChild
    接口,它是使用EIMI实现的,因此从外部既不可见也不可覆盖)。这是一个很好的起点

    (此外,您还需要考虑如何限制控件可以容纳的子控件的类型。使用泛型是一种选择,但我对XAML泛型的支持持怀疑态度。)