C# 将复选框添加到UniformGrid
我试图在wpf中动态地将复选框添加到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
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>