views:

55

answers:

4

Hi all,

I'm currently displaying RadioButtons in my application as rows of ToggleButtons (see my last question). However, I'd like the buttons to be of the same width - currently, every button is just as wide as it has to be.

Since I'm working with templates, I'd like to avoid specifying the width every time I use the control if possible - instead, the width of every button in the row should be equal to that of the widest button in that group.

Any ideas how to do this in XAML? :-)

A: 

in your resources section create a style that targets ToggleButtons and sets the width to whatever value you want.

<Window.Resources>
    <Style TargetType="{x:Type ToggleButton}">
        <Setter Property="Width" Value="50" />
    </Style>
</Window.Resources>
Scott M.
+6  A: 

Maybe using a UniformGrid and setting int the style the property HorizontalAlignement="Stretch" will help.

HCL
Just tried this out and it works very nicely, though you may want to put the UniformGrid inside a canvas so that it doesn't stretch to fill the entire control that it sits in (otherwise each button will be the size of the cell, rather than the size of the largest button). You do need to bind the Columns property to the number of buttons though. Also it doesn't look like you need to set the HorizontalAlignment.
Martin Harris
It depends on the container. For instance, here is one that is the ItemsPanel of an ItemsControl (forgive the formatting in the comment): <UniformGrid x:Name="gridLayout" IsItemsHost="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Columns="{Binding Path=ItemsSource.Count, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}" />
Wonko the Sane
In my eyes, `UniformGrid` definitely is the way to go! And you do not need to put it inside a `Canvas` to restrict its width. You can simply set its `HorizontalAlignment` property to `Left`. Also, the `Columns` property does not need to be bound to the number of buttons! You can simply set the `Rows` property to `1`, and it will create as many columns as needed to display all children.
gehho
Awesome idea! I'm going to check this out first thing tomorrow! :-)
Jan
Works like a charm - thanks y'all!
Jan
+4  A: 

If you have access to all the toggle buttons (e.g. they aren't databound) then there is a neat trick you can do by binding the minwidth of each button to the width of the one next to it. With the final button being bound to the first:

<StackPanel Orientation="Horizontal">
    <Button x:Name="Button1" Content="Long text" MinWidth="{Binding ElementName=Button2, Path=ActualWidth}"/>
    <Button x:Name="Button2" Content="A" MinWidth="{Binding ElementName=Button3, Path=ActualWidth}"/>
    <Button x:Name="Button3" Content="Extremely long text that should cause this button to be really wide" MinWidth="{Binding ElementName=Button1, Path=ActualWidth}"/>
</StackPanel>
Martin Harris
I was in the middle of writing up an ElementBinding answer myself. :) This solution was slightly more graceful than mine (binding Width to ActualWidth of known longest). The upside of your solution is that it would be fairly simple to implement if these controls are being added dynamically, or if the Content changes.
Wonko the Sane
+1 Wow, cool Idea.
HCL
Nice idea. However, I think a `UniformGrid` is a more comfortable and straight-forward solution. You can simply add buttons to the panel without worrying about `MinWidth` or any other stuff. It just works. Something like this `<UniformGrid Rows="1" HorizontalAlignment="Left"><Button Content="Foo"/><Button Content="Bar"/><Button Content="Foo Bar"/></UniformGrid>` will make all `Button`s have the same size as the "Foo Bar" button.
gehho
@gehho - I agree with you about the UniformGrid (and thanks for clarifying the columns thing, setting rows to 1 is *much* easier). I only posted this because I think it is quite nice that WPF handles recursive bindings correctly.
Martin Harris
A: 

Use a grid with a 1 button in each column and definethe widths like this

Daniel