Reputation: 2336
I'm learning WPF and can't figure out how to enfore my buttons to take a square shape.
Here is my XAML Markup:
<Window x:Class="Example"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="368" Width="333">
<Window.Resources>
<Style x:Key="ToggleStyle" BasedOn="{StaticResource {x:Type ToggleButton}}"
TargetType="{x:Type RadioButton}">
</Style>
</Window.Resources>
<RadioButton Style="{StaticResource ToggleStyle}">
Very very long text
</RadioButton>
</Window>
Specifying explicit values for Width
and Height
attributes seems like a wrong idea - the button should calculate its dimensions based on its contents automagically, but keep its width and height equal. Is this possible?
Upvotes: 38
Views: 30198
Reputation: 850
I found a simpler solution for the case where you want the button to expand and shrink, tipically when its text changes:
<RadioButton Style="{StaticResource ToggleStyle2}"
HorizontalAlignment="Center" VerticalAlignment="Center"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
Width="{Binding Path=ActualWidth, ElementName=txtblck_innerText }"
Height="{Binding Path=ActualWidth, ElementName=txtblck_innerText }">
<TextBlock x:Name="txtblck_innerText"
MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" >
Very very long text.........
</TextBlock>
</RadioButton>
This solution above applies when the size of the button is imposed by its content (comes from inside) as stated in the question.
However, in case you want a square button whose size is imposed by the place where it is going to be (comes from outside), for instance, the size of the grid cell that contains the button, a solution could be:
<RadioButton Style="{StaticResource ToggleStyle2}"
HorizontalAlignment="Center" VerticalAlignment="Center"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
<Viewbox Stretch="Uniform">
<Border Width="20" Height="20">
<Viewbox Stretch="Uniform">
<TextBlock x:Name="txtblck_innerText">
Very very long text...........
</TextBlock>
</Viewbox>
</Border>
</Viewbox>
</RadioButton>
Upvotes: 2
Reputation: 574
@Dan Pruzey's answer was good, but did not shrink the square if the window was downsized. What I found to work best was to set the height to auto and the width to that height:
<Button Height="Auto" Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"/>
This kept the button a square when sizing my window bigger and smaller. Hope this helps someone.
Upvotes: 5
Reputation: 985
The currently accepted answer cannot grow AND shrink. I think I found a better approach, by defining a custom style with a rectangle (stretched uniformly).
<Style x:Key="SquareButton" TargetType="Button">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#3a3a3a" />
<Setter Property="BorderBrush" Value="#5a5a5a"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border HorizontalAlignment="Center">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Rectangle Stretch="Uniform"
Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="4"
Margin="0"
Fill="{TemplateBinding Background}"
Panel.ZIndex="1"
/>
<ContentPresenter Margin="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Panel.ZIndex="2" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#4a4a4a"/>
</Trigger>
</Style.Triggers>
</Style>
Btw, you can also create a perfect round button this way. Just replace Rectangle with Ellipse.
Upvotes: 5
Reputation: 34208
Try this - it seems to work in Kaxaml:
<Button
MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
MinHeight="{Binding ActualWidth, RelativeSource={RelativeSource Self}}">
Some content
</Button>
(To test, I put a TextBox inside the button, because that's an easy way to change content size without re-parsing the Xaml.)
Edit: sorry, should probably have specified it as a style to match your example:
<Style TargetType="Button" x:Key="SquareButton">
<Setter Property="MinWidth" Value="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" />
<Setter Property="MinHeight" Value="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" />
</Style>
Upvotes: 57
Reputation: 5123
I think you want to bind button's width to its height, like this:
<Button Name="myButton"
Width="{Binding ElementName=myButton, Path=Height}"
Height="100">
Button Text
</Button>
Upvotes: 4