Reputation:
I have a set of buttons I am trying to make the same width, rather than the default width. However, the maximum width they should be is to make the button with the longest text display nicely.
First, I tried using a Grid
and using columns with a * width, but that filled the entire window. It was suggested that I use a UniformGrid
, but that had the same result. I cannot just set the width because the value in the button can change at any time by the user setting which language the button should display in.
I eventually set up a MultiBinding
and got things to almost work, with the button resizing up when the locale is changed. My problem now is that it does not resize back down.
Here is my XAML content; I hard-coded the text in so this should be copy/pasteable as-is:
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="0,10,0,0">
<Button Name="DeleteBranchOkButton"
Content="Ok"
HorizontalAlignment="Left"
Padding="5">
<Button.MinWidth>
<MultiBinding Converter="{StaticResource EqualWidthConverter}">
<Binding ElementName="DeleteBranchCancelButton" Path="ActualWidth" />
</MultiBinding>
</Button.MinWidth>
</Button>
<Button Name="DeleteBranchCancelButton"
Content="Cancel"
HorizontalAlignment="Left"
Margin="10,0,0,0"
Padding="5">
<Button.MinWidth>
<MultiBinding Converter="{StaticResource EqualWidthConverter}">
<Binding ElementName="DeleteBranchOkButton" Path="ActualWidth" />
</MultiBinding>
</Button.MinWidth>
</Button>
</StackPanel>
My converter implementation is:
public class EqualWidthConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return Math.Abs(values.Cast<double>().Max()) < .1 ? -1 : values.Cast<double>().Max();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new object[] {};
}
}
The problem now is allowing the buttons to resize back down if the language is changed and the buttons are wider than necessary. One potential solution I identified is injecting the settings control into each view, handling the languageChanged
event, and setting the MinWidth
property to 0 in the code behind.
I would rather not do that, however, unless it is the only method possible; I would much rather have each control not need to know about the settings implementation. Is there a better way to do this, perhaps without even needing the converter?
This is what using a Grid
results in:
This is what I want:
Upvotes: 1
Views: 1654
Reputation: 7918
There are several possible solutions to your problem. The most trivial and straightforward would be using Buttons
of equal size placed either within the layout Grid
control with three equally-sized columns (use *) and Buttons'
properties set to default Stretch mode, or place them into StackPanel
(as per your sample); then encapsulate the Button's
TexBlock
into:
<Viewbox>
<TextBlock Text="YourText" Style="{Optional}"/>
</Viewbox>
in order to resize/fit the content nicely.
Upvotes: 0
Reputation: 3230
Grid.IsSharedSizeScope and SharedSizeGroup to the rescue! These two properties let you specify grid columns/rows to share the same width/height, even across multiple grids.
Solution without wrapping
<Grid Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Column="0">New Branch</Button>
<Button Grid.Column="1">Merge</Button>
<Button Grid.Column="2">Delete Branch in French!</Button>
</Grid>
Solution with wrapping
<WrapPanel Grid.IsSharedSizeScope="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button>New Branch</Button>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button>Merge</Button>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="a"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button>Delete Branch in French!</Button>
</Grid>
</WrapPanel>
Upvotes: 6