Evenly-sized buttons according to content of largest button
Imagine I have two WPF buttons on a window, with content as follows:
<Button>OK</Button>
<Button>Cancel</Button>
I want these buttons to be the same width, however in a scenario where the Content
is bound to a localised value for a given user's language, I don't know how wide the buttons need to be to accommodate the new c开发者_如何学JAVAontent.
How might I apply a minimum width to these buttons, such that the width of the widest one (according to content) is effectively used as the MinWidth
of both, thus keeping them uniform?
Or to put it another way: I don't want the buttons to be the width of their container (unless using a container in a clever way is the answer to my problem), and I don't want them each to just size to their own content because that will make them different sizes. I want something in-between. The one with the largest content to size to display it's content, and all others to size to that same width, so the widths are all equal.
I expect the answer lies in putting them in some sort of container. I know I could use a Grid
and let them fill grid "cells", but the point is I don't want them to be too wide, either. I know I could have some code-behind that runs on the Content_Changed
event of the buttons and sets the minwidth to that of the widest button, but I'm interested in a pure-xaml method. It might be I need to create a custom control extending ItemsControl
that rusn code-behind when new items are added or re-sized and applies the width of the widest item as the MinWidth
of all the other items.
Many thanks in advance.
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>
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.
精彩评论