C# 将复选框添加到UniformGrid

C# 将复选框添加到UniformGrid,c#,wpf,checkbox,uniformgrid,C#,Wpf,Checkbox,Uniformgrid,我试图在wpf中动态地将复选框添加到uniformgrid。 但看起来网格没有给它们分配足够的空间,所以它们都有点相互重叠。 这是我在代码隐藏中添加它们的方式: foreach (string folder in subfolders) { PathCheckBox chk = new PathCheckBox(); chk.Content = new DirectoryInfo(folder).Name; chk.FullPath = folder; chk.Horizonta

我试图在wpf中动态地将复选框添加到uniformgrid。 但看起来网格没有给它们分配足够的空间,所以它们都有点相互重叠。 这是我在代码隐藏中添加它们的方式:

foreach (string folder in subfolders)
{
  PathCheckBox chk = new PathCheckBox();
  chk.Content = new DirectoryInfo(folder).Name;
  chk.FullPath = folder;
  chk.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
  chk.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;        

  unfiformGridSubfolders.Children.Add(chk);
}
这就是我的XAML的外观(我在scrollviewer中放置了uniformgrid)


这就是它在程序中的外观:


我只是希望每个复选框都有足够的空间,以便可以完全阅读内容。

我建议使用类似于
WrapPanel


那么我该怎么做呢,每个单元格都有最大内容的复选框大小


使用UniformGrid,您必须手动检查每个复选框,检查其大小,并将Uniform Grid.Columns修改为类似于
Math.Floor(Grid.CurrentWidth/CheckBoxMaxWidth)的内容

UniformGrid
属性都设置为零时,
UniformGrid
尝试将元素布置在正方形中,而不考虑元素的大小。我将编写一个面板,按照您的需要对元素进行布局,如下所示。只需在XAML中使用
MyPanel
而不是
UniformGrid

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace MyNamespace
{
    class MyPanel : Panel
    {
        int columns;
        int rows;

        protected override Size MeasureOverride (Size constraint)
        {
            Size childConstraint = constraint;
            double maxChildDesiredWidth = 0.0;
            double maxChildDesiredHeight = 0.0;

            if (InternalChildren.Count > 0)
            {
                for (int i = 0, count = InternalChildren.Count; i < count; ++i)
                {
                    UIElement child = InternalChildren[i];

                    // Measure the child.
                    child.Measure (childConstraint);
                    Size childDesiredSize = child.DesiredSize;

                    if (maxChildDesiredWidth < childDesiredSize.Width)
                    {
                        maxChildDesiredWidth = childDesiredSize.Width;
                    }

                    if (maxChildDesiredHeight < childDesiredSize.Height)
                    {
                        maxChildDesiredHeight = childDesiredSize.Height;
                    }
                }

                columns = (int)(constraint.Width / maxChildDesiredWidth);
                rows = (int)(InternalChildren.Count / columns + 0.5);
            }
            else
            {
                columns = 0;
                rows = 0;
            }

            return new Size ((maxChildDesiredWidth * columns), (maxChildDesiredHeight * rows));
        }

        protected override Size ArrangeOverride (Size arrangeSize)
        {
            Rect childBounds = new Rect (0, 0, arrangeSize.Width / columns, arrangeSize.Height / rows);
            double xStep = childBounds.Width;
            double xBound = arrangeSize.Width - 1.0;

            childBounds.X += 0;

            foreach (UIElement child in InternalChildren)
            {
                child.Arrange (childBounds);

                if (child.Visibility != Visibility.Collapsed)
                {
                    childBounds.X += xStep;
                    if (childBounds.X >= xBound)
                    {
                        childBounds.Y += childBounds.Height;
                        childBounds.X = 0;
                    }
                }
            }

            return arrangeSize;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
名称空间MyNamespace
{
类别MyPanel:Panel
{
int列;
int行;
受保护的覆盖尺寸测量覆盖(尺寸约束)
{
大小约束=约束;
双maxChildDesiredWidth=0.0;
双maxChildDesiredHeight=0.0;
如果(InternalChildren.Count>0)
{
for(int i=0,count=InternalChildren.count;i=xBound)
{
childBounds.Y+=childBounds.Height;
childBounds.X=0;
}
}
}
返回安排大小;
}
}
}

您必须动态添加UI元素吗?你不能预先定义你的
复选框
模板,然后添加
复选框。内容
?如果可能,则定义一个包含您的
复选框的
可观察集合

public ObservableCollection<string> SubfolderNames { get; set; }

这样,所有项目的宽度都与它们共享一个大小组的宽度相同,而且因为它们的大小是
Auto
,所以它们的大小也将设置为最大的
复选框。内容

您希望实现什么?如果有一个文件夹占据了整个宽度怎么办?你想让所有东西都占据整个宽度吗?UniformGrid,使每个单元格统一,这意味着所有单元格的大小都相同。那么,如何做到这一点,即每个单元格的大小都与包含最大内容的复选框的大小相同?请尝试包装。或者设置一个样式来设置所有复选框的宽度,但由于溢出,最终会出现滚动条,这不是一个很好的解决方案(请参见前面的注释)
public ObservableCollection<string> SubfolderNames { get; set; }
    <ItemsControl Grid.Row="0" x:Name="gridSubfolders" ItemsSource="{Binding SubfolderNames}" Grid.IsSharedSizeScope="True">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel></WrapPanel>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" SharedSizeGroup="50" />
                    </Grid.ColumnDefinitions>
                    <Border Margin="5" BorderThickness="1" BorderBrush="Black">
                        <CheckBox Content="{Binding}"/>
                    </Border>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>