Reputation: 9475
There are similar questions to this here and here, but I've tried everything in both of them and they don't fix my problem.
I want to show a grid of checkBoxes on screen in a WPF (layout) grid. These checkboxes have variable length text. I want all the columns to be the same width, and them all to show the text without truncation. That is, I need them all to have the width of the longest text. I want the screen itself to size to content. That is, to be just wide enough to show all the checkboxes.
The list of checkboxes is variable depending on other factors, so I'm using an ItemsControl to show them. A simplified version of the code is below.
If you run this the column with 'Long Text', which is the second column, is much wider than the columns with shorter text. To make them all the same width I've tried using a SharedSizeGroup, and also tried setting MaxWidth = ActualWidth in a column loaded event, which are solutions suggested elsewhere, but these don't work.
I'm sure there must be an easy answer to this, it seems a fairly basic thing to want to do with a layout control. What am I doing wrong please?
XAML:
<Window x:Class="GridColsEqualSize.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" SizeToContent="WidthAndHeight" FontSize="25">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <!-- In the real project second row is for OK/Cancel buttons -->
</Grid.RowDefinitions>
<ItemsControl ItemsSource="{Binding CheckBoxItems}" Grid.Row="0" Grid.Column="0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<!--Whatever I do I can't get the screen to resize and the cols to have the same width-->
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Text}" IsChecked="{Binding Enabled}"
Margin="0,0,10,0"></CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Style.Setters>
<Setter Property="Grid.Row" Value="{Binding GridRow}" />
<Setter Property="Grid.Column" Value="{Binding GridColumn}" />
</Style.Setters>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</Window>
C#:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
CheckBoxItems = new List<CheckBoxItem>
{
new CheckBoxItem("A", true),
new CheckBoxItem("B"),
new CheckBoxItem("C", true),
new CheckBoxItem("D"),
new CheckBoxItem("E", true),
new CheckBoxItem("F"),
new CheckBoxItem("G"),
new CheckBoxItem("Long text", true),
new CheckBoxItem("")
};
SetCheckBoxItemRowsAndColumns();
}
public List<CheckBoxItem> CheckBoxItems { get; set; }
private void SetCheckBoxItemRowsAndColumns()
{
int currentColumn = 0;
int currentRow = 0;
foreach (CheckBoxItem checkBoxItem in CheckBoxItems)
{
checkBoxItem.GridColumn = currentColumn;
checkBoxItem.GridRow = currentRow;
if (currentColumn != 2)
{
currentColumn++;
}
else
{
currentRow++;
currentColumn = 0;
}
}
}
public class CheckBoxItem
{
public CheckBoxItem(string text, bool enabled = false)
{
Text = text;
Enabled = enabled;
}
public string Text { get; set; }
public bool Enabled { get; set; }
public int GridRow { get; set; }
public int GridColumn { get; set; }
}
private void FrameworkContentElement_OnLoaded(object sender, RoutedEventArgs e)
{
((ColumnDefinition)sender).MaxWidth = ((ColumnDefinition)sender).ActualWidth;
}
}
Upvotes: 2
Views: 2742
Reputation: 511
Everything is Ok :) you've choose the right solution 'SharedSizeGroup'
You have only to add Grid.IsSharedSizeScope="True" to your ItemsControl :
...
</Grid.RowDefinitions>
<ItemsControl Grid.IsSharedSizeScope="True" ItemsSource="{Binding CheckBoxItems}" Grid.Row="0" Grid.Column="0" >
<ItemsControl.ItemsPanel>
...
Upvotes: 4