none
OK and Cancel buttons of the same width RRS feed

  • Question

  • When dealing with dialogs there is often a need to have OK and Cancel button in the bottom right corner as the standard interface. With the WPF's content model all buttons are sized to their content but for the aesthetic purpose I need these two buttons to have the same width. So consider this short code:

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
       <Button>OK</Button>
       <Button>Cancel</Button>
    </StackPanel>

    Note the horizontal StackPanel.
    So how can I make the width of those be equal with the least amount of XAML code and without hardcoding or any other bad practice?
    • Edited by shtreber Friday, August 29, 2008 12:17 AM edit
    Friday, August 29, 2008 12:11 AM

Answers

  • Here's one (of many) solutions:

     
    <UniformGrid HorizontalAlignment="Right" Rows="1" Columns="2">  
       <Button>OK</Button> 
       <Button>Cancel</Button> 
    </UniformGrid> 
     

    (Note that I would not characterize hardcoding a size as a bad practice... especially when it comes to design.)


    Dr. WPF - Online Office at http://drwpf.com/blog/
    • Marked as answer by shtreber Friday, August 29, 2008 1:28 AM
    Friday, August 29, 2008 12:35 AM
  • Yeah, '*' sizing falls apart for a size-to-content grid.  If you set an explicit width on the grid, then it will evenly subdivide the space (but then you no longer have size-to-content).  Basically, it comes down to this... something has to win.  '*' means to subdivide the remaining space evenly, but if you are size-to-content, there is no remaining space to subdivide.  In that case, the columns essentially behave like auto sized columns.

    UniformGrid has a much simpler algorithm...  It just uses the size of the largest child as the uniform size.

    Another option would be a StackPanel in which you bind the Width of the OK button to the ActualWidth property on the Cancel button.  This works great until you try to localize the app for some language where the word OK is wider than Cancel.  :)
    Dr. WPF - Online Office at http://drwpf.com/blog/
    • Marked as answer by shtreber Friday, August 29, 2008 5:15 PM
    Friday, August 29, 2008 1:44 AM

All replies

  • Here's one (of many) solutions:

     
    <UniformGrid HorizontalAlignment="Right" Rows="1" Columns="2">  
       <Button>OK</Button> 
       <Button>Cancel</Button> 
    </UniformGrid> 
     

    (Note that I would not characterize hardcoding a size as a bad practice... especially when it comes to design.)


    Dr. WPF - Online Office at http://drwpf.com/blog/
    • Marked as answer by shtreber Friday, August 29, 2008 1:28 AM
    Friday, August 29, 2008 12:35 AM
  • Can't you just add a "Width="150" attribute to your <Button> tags?
    Friday, August 29, 2008 1:18 AM
  • Oh it's that simple! Thanks Dr.WPF.
    BTW I tried with this code before posting this question

                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="0.5*"></ColumnDefinition>
                            <ColumnDefinition Width="0.5*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                   
                       <Button Grid.Column="0">Cancel</Button>   
                       <Button Grid.Column="1">OK</Button>   

                    </Grid>

    But it doesnt work, "Cancel" is still wider than "OK". I wonder why this doesnt have the same effect as UniformGrid?
    I've set Width for each column to be equally allocated among its children like uniform grid does.
    • Edited by shtreber Friday, August 29, 2008 1:34 AM edit
    Friday, August 29, 2008 1:33 AM
  • Yeah, '*' sizing falls apart for a size-to-content grid.  If you set an explicit width on the grid, then it will evenly subdivide the space (but then you no longer have size-to-content).  Basically, it comes down to this... something has to win.  '*' means to subdivide the remaining space evenly, but if you are size-to-content, there is no remaining space to subdivide.  In that case, the columns essentially behave like auto sized columns.

    UniformGrid has a much simpler algorithm...  It just uses the size of the largest child as the uniform size.

    Another option would be a StackPanel in which you bind the Width of the OK button to the ActualWidth property on the Cancel button.  This works great until you try to localize the app for some language where the word OK is wider than Cancel.  :)
    Dr. WPF - Online Office at http://drwpf.com/blog/
    • Marked as answer by shtreber Friday, August 29, 2008 5:15 PM
    Friday, August 29, 2008 1:44 AM