Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.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# WPF 2列布局容器_C#_Wpf_Wrappanel_Uniformgrid - Fatal编程技术网

C# WPF 2列布局容器

C# WPF 2列布局容器,c#,wpf,wrappanel,uniformgrid,C#,Wpf,Wrappanel,Uniformgrid,如何创建可以用作ItemsControl的ItemsPanel的布局容器 将项目堆叠在两列中,并将右列用于左列中没有足够空间的剩余项目(类似于混合了包裹面板的统一网格) 例如: 高度大致相同的四个项目将显示如下: 其中两个宽度明显较小的四个项目如下所示: 尝试垂直方向的包装 <WrapPanel Orientation="Vertical" Height="200"> <Border BorderBrush="Red" BorderThickness="2" Heig

如何创建可以用作
ItemsControl的
ItemsPanel
的布局容器 将项目堆叠在两列中,并将右列用于左列中没有足够空间的剩余项目(类似于混合了包裹面板的统一网格)

例如:

高度大致相同的四个项目将显示如下:

其中两个宽度明显较小的四个项目如下所示:


尝试垂直方向的包装

<WrapPanel Orientation="Vertical" Height="200">
    <Border BorderBrush="Red" BorderThickness="2" Height="100" Width="100"/>
    <Border BorderBrush="Red" BorderThickness="2" Height="100"  Width="100"/>
    <Border BorderBrush="Red" BorderThickness="2" Height="100"  Width="100"/>
    <Border BorderBrush="Red" BorderThickness="2" Height="100"  Width="100"/>
</WrapPanel>

输出


输出

编辑:因为您的评论说wrappanel不符合您的要求。让我们根据您的要求创建我们的面板

下面是一个自定义面板,它垂直设置控件,当子控件的高度超过面板高度时,它会将子控件移动到下一列,与垂直方向的WrapPanel完全相同,但它有一个属性列,用户可以在xaml中指定,并且该面板创建的列数不会超过该列值

CustomPanel.cs

公共类自定义面板:面板
{
//TODO:创建为附着属性
公共int列{get;set;}
//默认公共构造函数
public CustomPanel():base()
{
}
受保护的覆盖尺寸测量覆盖(尺寸可用尺寸)
{
大小=排列和测量(可用大小,真);
if(double.IsInfinity(availableSize.Height)| | double.IsInfinity(availableSize.Width))
返回大小;
其他的
返回可用性;
}
受保护的替代尺寸排列替代(尺寸最终化)
{
返回安排和测量(最终化,假);
}
尺寸安排和测量(尺寸最终确定、尺寸测量)
{
//如果未指定列,则将其值设置为1。
列=列==0?1:列;
尺寸=新尺寸(0,0);
双最大宽度=0.0;
int colCount=1;
foreach(InternalChildren中的UIElement子元素)
{
if((size.Height+child.DesiredSize.Height>finalSize.Height)&&Columns>=colCount)
{
//如果所有高度都已消耗,请移至下一列
尺寸.宽度+=最大宽度;
尺寸。高度=0.0;
colCount++;
}
if(isMeasure)
儿童。测量(最终化);
其他的
排列(新矩形(新点(大小.宽度,大小.高度),子.DesiredSize));
size.Height+=child.DesiredSize.Height;
if(maxWidth
xaml


输出

xaml


输出

xaml


输出


尝试垂直方向的WrapPanel

<WrapPanel Orientation="Vertical" Height="200">
    <Border BorderBrush="Red" BorderThickness="2" Height="100" Width="100"/>
    <Border BorderBrush="Red" BorderThickness="2" Height="100"  Width="100"/>
    <Border BorderBrush="Red" BorderThickness="2" Height="100"  Width="100"/>
    <Border BorderBrush="Red" BorderThickness="2" Height="100"  Width="100"/>
</WrapPanel>

输出


输出

编辑:因为您的评论说wrappanel不符合您的要求。让我们根据您的要求创建我们的面板

下面是一个自定义面板,它垂直设置控件,当子控件的高度超过面板高度时,它会将子控件移动到下一列,与垂直方向的WrapPanel完全相同,但它有一个属性列,用户可以在xaml中指定,并且该面板创建的列数不会超过该列值

CustomPanel.cs

公共类自定义面板:面板
{
//TODO:创建为附着属性
公共int列{get;set;}
//默认公共构造函数
public CustomPanel():base()
{
}
受保护的覆盖尺寸测量覆盖(尺寸可用尺寸)
{
大小=排列和测量(可用大小,真);
if(double.IsInfinity(availableSize.Height)| | double.IsInfinity(availableSize.Width))
返回大小;
其他的
返回可用性;
}
受保护的替代尺寸排列替代(尺寸最终化)
{
返回安排和测量(最终化,假);
}
尺寸安排和测量(尺寸最终确定、尺寸测量)
{
//如果未指定列,则将其值设置为1。
列=列==0?1:列;
尺寸=新尺寸(0,0);
双最大宽度=0.0;
int colCount=1;
foreach(InternalChildren中的UIElement子元素)
{
if((size.Height+child.DesiredSize.Height>finalSize.Height)&&Columns>=colCount)
{
//如果所有高度都已消耗,请移至下一列
尺寸.宽度+=最大宽度;
尺寸。高度=0.0;
colCount++;
}
if(isMeasure)
儿童。测量(最终化);
其他的
排列(新矩形(新点(大小.宽度,大小.高度),子.DesiredSize));
size.Height+=child.DesiredSize.Height;
if(maxWidth
xaml


输出

xaml


输出

xaml


输出


谢谢你的回答。问题是,当窗口调整到更大的宽度时,wrapPanel会将其扩展到两列以上,我不希望这样…请参阅编辑部分。我希望这会有所帮助。+1获得详细答案。非常感谢!我选择了自定义布局方向,但创建了自己的面板,因为您的解决方案对我来说不太合适。不幸的是,由于公司的政策,我不能在这里共享我的代码,所以我将接受
    public class CustomPanel : Panel
{
    //TODO :Create as Attached Property
    public int Columns { get; set; }

    // Default public constructor 
    public CustomPanel(): base()
    {
    }

    protected override Size MeasureOverride(Size availableSize)
    {
        Size size = ArrangeAndMeasure(availableSize, true);
        if (double.IsInfinity(availableSize.Height) || double.IsInfinity(availableSize.Width))
            return size;
        else
            return availableSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        return ArrangeAndMeasure(finalSize, false);
    }

    Size ArrangeAndMeasure(Size finalSize,bool isMeasure)
    {
        //if columns not specified set it value 1.
        Columns = Columns == 0 ? 1 : Columns;
        Size size = new Size(0, 0);
        double maxWidth = 0.0;
        int colCount = 1;

        foreach (UIElement child in InternalChildren)
        {
            if ((size.Height + child.DesiredSize.Height > finalSize.Height) && Columns >= colCount)
            {
                //if all height consumed move to next column
                size.Width += maxWidth;
                size.Height = 0.0;
                colCount++;
            }

            if (isMeasure)
                child.Measure(finalSize);
            else
                child.Arrange(new Rect(new Point(size.Width, size.Height), child.DesiredSize));

            size.Height += child.DesiredSize.Height;

            if (maxWidth < child.DesiredSize.Width)
                maxWidth = child.DesiredSize.Width;
        }
        return size; 
    }
}
 <local:CustomPanel Height="200" Columns="2">
    <Border BorderBrush="LimeGreen" BorderThickness="2" Height="200" Width="100"  />
    <Border BorderBrush="Red" BorderThickness="2" Height="50"  Width="100"  />
    <Border BorderBrush="Black" BorderThickness="2" Height="50"  Width="100"  />
    <Border BorderBrush="Blue" BorderThickness="2" Height="50"  Width="100"  />
    <Border BorderBrush="Yellow" BorderThickness="2" Height="50"  Width="100"  />
</local:CustomPanel>
 <local:CustomPanel Height="200" Columns="2">
    <Border BorderBrush="Red" BorderThickness="2" Height="50"  Width="100"  />
    <Border BorderBrush="Black" BorderThickness="2" Height="50"  Width="100"  />
    <Border BorderBrush="Blue" BorderThickness="2" Height="50"  Width="100"  />
    <Border BorderBrush="Yellow" BorderThickness="2" Height="50"  Width="100"  />
</local:CustomPanel>
<local:CustomPanel Height="200" Columns="2">
    <Border BorderBrush="Red" BorderThickness="2" Height="50"  Width="100"  />
    <Border BorderBrush="Black" BorderThickness="2" Height="50"  Width="100"  />
    <Border BorderBrush="Blue" BorderThickness="2" Height="50"  Width="100"  />
    <Border BorderBrush="Yellow" BorderThickness="2" Height="200"  Width="100"  />
</local:CustomPanel>