tags:

views:

1490

answers:

6

The button below always expands to be as wide as the TextBlock. I've tried StackPanel, DockPanel, Width="Auto", etc.

How can I make the button expand to the size of its own text (as in HTML) and not to the size of text in its environement?

    <DockPanel HorizontalAlignment="Left">
        <Button x:Name="ButtonFavorite"
                DockPanel.Dock="Top"  
                Content="Customers" 
                Margin="10" 
                Width="Auto"
                Click="ButtonFavorite_Click">
        </Button>

        <TextBlock DockPanel.Dock="Top" Text="this is a long text which makes the button stretch across the window, if this text is just a couple words, the button will be smaller, and this drives me up the wall"  Margin="10" TextWrapping="Wrap" />

    </DockPanel>

ANSWER:

Thanks Greg, that did it. Here is the full XAML that works now, you can right-click the button to change its Content so see that the button expands and contracts appropriately.

<Window x:Class="Test3784234.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <DockPanel HorizontalAlignment="Left">
        <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" >
            <Button x:Name="ButtonFavorite"
                    Padding="5"
                    Cursor="Hand" 
                    DockPanel.Dock="Top"  
                    Content="Customers" 
                    Margin="10" 
                    Click="ButtonFavorite_Click">
                <Button.ContextMenu>
                    <ContextMenu>
                        <MenuItem x:Name="menuItemReports" Header="Reports" Click="MenuItem_Click" />
                        <MenuItem x:Name="menuItemContracts" Header="Contracts" Click="MenuItem_Click"/>
                        <MenuItem x:Name="menuItemCustomers" Header="Customers" Click="MenuItem_Click" />
                        <MenuItem x:Name="menuItemDocumentation" Header="Documentation Creation Instructions" Click="MenuItem_Click" />
                        <MenuItem x:Name="menuItemEmail" Header="E-Mail" Click="MenuItem_Click" />
                    </ContextMenu>
                </Button.ContextMenu>
            </Button>

        </StackPanel>

        <TextBlock x:Name="TheMessage" DockPanel.Dock="Top" Text="Right-click the 'favorites' button to change its function." Margin="10" TextWrapping="Wrap"/>

    </DockPanel>
</Window>
A: 

Can you place them in a two column Grid with the button spanning just one column and the text spanning two columns?

Michael Prewecki
I just tried that but it is the same as giving the button an absolute width which I don't want to do since the Content will be dynamic.
Edward Tanguay
+1  A: 

Regarding your annoyance at the sizing of buttons, this is something that seems to be targeted at the designer in the designer/developer workflow, while you're clearly working on the developer portion. For the sake of development, I always apply a few styles in my App.xaml to ensure somewhat better button sizing. For example, in the application tag in your app.xaml file:

<Application.Resources>
  <Style TargetType="Button">
    <Setter Property="MinWidth" Value="60" />
    <Setter Property="MinHeight" Value="23" />
    <Setter Property="Margin" Value="3" />
  </Style>
</Application.Resources>

Regarding your actual question:

The problem is that your DockPanel is stretching to the width of the text and the button will naturally expand to fill the available area. If you want the quick and dirty solution you can do something like:

<DockPanel HorizontalAlignment="Left">
    <Button x:Name="ButtonFavorite"
            DockPanel.Dock="Top"  
            Content="Customers" 
            Margin="10" 
            Width="Auto"
            MaxWidth="100"
            Click="ButtonFavorite_Click">
    </Button>
</DockPanel>

Note the MaxWidth. If you want a more composable result, isolate your button in another panel. (I'm using a stackpanel because I believe someone else already used a grid in their example):

<DockPanel HorizontalAlignment="Left">
    <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
        <Button x:Name="ButtonFavorite"
            Content="Customers" 
            Margin="10" 
            Width="Auto"
            Click="ButtonFavorite_Click" />
    </StackPanel>
    <TextBlock DockPanel.Dock="Top" Text="this is a long text which makes the button stretch across the window, if this text is just a couple words, the button will be smaller, and this drives me up the wall"  Margin="10" TextWrapping="Wrap" />
</DockPanel>

I like the StackPanel in this case because I find myself using it to create the horizontal "bar" of buttons along the bottom of a Form- err- Window in the right corner.

Greg D
regarding your Application.Resources idea, I tried it out with a button inside a Grid.Row which has a height of 10 and the button unfortunately does not expand its height its MinHeight. I would like to find something which allows buttons to not be so sensitive to their surroundings.
Edward Tanguay
regarding your MaxWidth idea, that has the same issue as just setting the width, if the button might be called "Application Creation Instructions" or might be called "Help" and I want the button to resize accordingly.
Edward Tanguay
Please note that MaxWidth is the hack solution. As you see, I think the more composable solution is the StackPanel with Orientation="Horizontal"
Greg D
Yes, the third one did it. Excellent, thanks!
Edward Tanguay
I'm not sure what the problem is that you had with the Application.Resources. Because there's no key, those settings should be universally applied to all buttons unless the button has a setting itself that supercedes it.
Greg D
Glad I could help. :)
Greg D
+1  A: 

You could try isolating the button from the main panel by putting it in another panel.

<DockPanel HorizontalAlignment="Left">
    <Grid DockPanel.Dock="Top">
        <Button x:Name="ButtonFavorite"
                Content="Customers" 
                Margin="10" 
                Width="Auto"
                Click="ButtonFavorite_Click">
        </Button>
    </Grid>

    <TextBlock DockPanel.Dock="Top" Text="this is a long text which makes the button stretch across the window, if this text is just a couple words, the button will be smaller, and this drives me up the wall"  Margin="10" TextWrapping="Wrap" />

</DockPanel>
Cameron MacFarland
A: 

I think Michael's approach should work. Just make sure to set the width of the first column to "Auto"

Jacob Adams
+1  A: 

All you need to do is set the HorizontalAlignment property on your button. It defaults to stretch therefore filling the available space.

<Button x:Name="ButtonFavorite"
        HorizontalAlignment="Left"
        Content="Customers" 
        Margin="10" 
        Width="Auto"
        Click="ButtonFavorite_Click">
Bryan Anderson
Hmmm, coming from a web developer background, I don't see the sense in having buttons "default to stretch to fill the available space".
Edward Tanguay
It was a design decision that was made so they could treat all controls the same across all cultures. Should they have made it default left when some cultures read right to left? HTML was developed from a more US-centric perspective.
Bryan Anderson
A: 

Here's an example using a Grid layout versus a DockPanel. The idea is to have 2 columns and 2 rows. Put the Button it a single cell and make that row/column pair auto-sizing. Then put the TextBox into the second row and have it span both of the columns. This will essentially make the top-right cell just filler space and will achieve the behavior you're looking for.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>

    <Button 
        x:Name="ButtonFavorite"
        Grid.Column="0"
        Grid.Row="0"
        Content="Customers" 
        Margin="10" 
        Width="Auto"
        Click="ButtonFavorite_Click">
    </Button>

    <TextBlock 
        Grid.Column="0"
        Grid.ColumnSpan="2"
        Grid.Row="1"
        Margin="10" 
        TextWrapping="Wrap"
        Text="this is a long text which makes the button stretch across the window, if this text is just a couple words, the button will be smaller, and this drives me up the wall" />
</Grid>
JaredPar