Imagine I have two WPF buttons on a window, with content as follows:
I
I like using a wrap panel for this type of scenario. When it's loaded I get the max width from all children using linq
. (assuming children are all buttons)
xaml
<WrapPanel Name="WP_ButtonSelections" Orientation="Horizontal" HorizontalAlignment="Center" Loaded="WP_ButtonSelections_Loaded"></WrapPanel>
cs
WP_ButtonSelections.Children.Add(new Button() { Content = "Hello" });
WP_ButtonSelections.Children.Add(new Button() { Content = "Hello World" });
private void WP_ButtonSelections_Loaded(object sender, RoutedEventArgs e)
{
double maxWidth = WP_ButtonSelections.Children.OfType<FrameworkElement>().Max(elm => elm.ActualWidth);
WP_ButtonSelections.Children.OfType<FrameworkElement>().ToList().ForEach(elm => elm.Width = maxWidth);
}
I needed a programmatic solution. This requires the loaded event because programmatically added buttons wont have an ActualWidth
defined upon calling WP_ButtonSelections.Children.Add()
. This solution should work with xaml defined buttons, or a mixture of both xaml and programmatic.
The Grid
<Grid HorizontalAlignment="Right" Grid.IsSharedSizeScope="true">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
<ColumnDefinition SharedSizeGroup="A"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<Button Grid.Column="0" Content="OK"/>
<Button Grid.Column="1" Content="Cancel"/>
</Grid.Children>
</Grid>
This can be broken up, you just need to set the IsSharedSizeScope on a common ancestor, e.g.:
<StackPanel Grid.IsSharedSizeScope="true">
<Grid HorizontalAlignment="Right">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<Button Grid.Column="0" Content="OK"/>
</Grid.Children>
</Grid>
<!-- ... -->
<Grid HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<Button Grid.Column="0" Content="Cancel"/>
</Grid.Children>
</Grid>
</StackPanel>
To prevent the buttons from becoming too large change the HorizontalAlignment
of the Grid to something else than Stretch
or set a MaxWidth
.
Use UniformGrid
<UniformGrid HorizontalAlignment="Right" Rows="1" Columns="2">
<Button Content="Ok" Grid.Column="0"/>
<Button Content="Cancel" Grid.Column="1"/>
</UniformGrid>