问题
I am trying to dynamically add checkboxes to an uniformgrid in wpf. But it looks like the grid doesn't allocate them enough space and so they all kinda lay over each other. This is how I add them in code behind:
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);
}
This is how my XAML looks (I placed the uniformgrid in a scrollviewer)
<ScrollViewer Grid.Column="1" Grid.RowSpan="3">
<UniformGrid x:Name="unfiformGridSubfolders" Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</ScrollViewer>
And this is how it looks in the program:
I just want that every checkBox has enough space, so that the content can be fully read.
回答1:
do you have to add UI elements dynamically? can't you just predefine your CheckBox
template and add CheckBox.Content
instead? If it's possible then define an ObservableCollection
that contains your CheckBox.Content
like this:
public ObservableCollection<string> SubfolderNames { get; set; }
then define an ItemsControl
and bind it's ItemsSource
to your collection:
<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>
This way, All Items have the same width as they share a size group, moreover because they are sized Auto
, they will also size to the largest CheckBox.Content
.
回答2:
I would suggest using something like WrapPanel
Then how can I do it, that each cell has the size of the checkBox with the biggest content?
Using a UniformGrid You would have to manually go through each checkbox, checking its size, and modifying the Uniform Grid.Columns to something like Math.Floor(Grid.CurrentWidth / CheckBoxMaxWidth)
回答3:
When the Rows
and the Columns
property of a UniformGrid
are both set to zero the UniformGrid
tries to layout the elements in a square without regarding the size of the elements. I'd write a panel that layouts your elements as you want it like the following one. Just use MyPanel
instead of UniformGrid
in your XAML.
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;
}
}
}
来源:https://stackoverflow.com/questions/30557660/adding-checkboxes-to-uniformgrid