David Yaw
David Yaw

Reputation: 27864

Autosize to only some controls

I'm working on a WPF GUI, and I want the window to auto-size to the content, but not to everything: I have some various buttons & other controls, and I want to autosize the width to that. If I add a long item to the list box, I want the window to stay the same size.

Example code:

<Window x:Class="QuickieWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="WidthAndHeight" ResizeMode="CanMinimize">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal">
            <Button Width="100" Content="Foo" Click="Button_Click"/>
            <Button Width="100" Content="Bar" Click="Button_Click"/>
            <Button Width="100" Content="Baz" Click="Button_Click"/>
        </StackPanel>
        <ListBox Grid.Row="1" Name="TheList" Height="100"/>
    </Grid>
</Window>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        string str = "This is a really long text item that will be wider than the " +
            "three buttons. I want a horizontal scrollbar on the listbox, not a wider " +
            "window. I want the window to size to the buttons, not to this listbox.";
        this.TheList.Items.Add(str);
    }
}

Initially, the window is sized to the buttons:

enter image description here

After adding a long item to the list box, I currently get this:

enter image description here

But I'd rather get this:

enter image description here

(I did that last screenshot by setting MaxWidth on the list box, but that isn't a good solution for the full application: In the full application, it's more than just three buttons; it's buttons, icons, textboxes, labels, etc, and I want the window to autosize to the whole mess, but not to the listbox at the bottom.)

Upvotes: 2

Views: 90

Answers (3)

mark_h
mark_h

Reputation: 5477

Give your stackPanel a name, e.g.

<StackPanel Name="MyPanel" Orientation="Horizontal">

Then in BOTH your list box and window properties add this;

Width="{Binding ElementName=MyPanel, Path=ActualWidth}"

You will need to include horizontal scrolling in your listbox.

Upvotes: 0

Xiaoy312
Xiaoy312

Reputation: 14477

You have to limit the width of the ListBox, else the parent window would just resize with whichever the control that take the most space due to SizeToContent="WidthAndHeight".

    <StackPanel Orientation="Horizontal">
        <Button Width="100" Content="Foo" Click="Button_Click"/>
        <Button Width="100" Content="Bar" Click="Button_Click"/>
        <Button Width="100" Content="Baz" Click="Button_Click"/>
    </StackPanel>

    <!-- set the width to 300 -->
    <ListBox Grid.Row="1" Name="TheList" Height="100" Width="300" />

Upvotes: 0

Evk
Evk

Reputation: 101463

You can bind width of content you do not want to autosize to the actual width of content you do, for example:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal" x:Name="panel">
        <Button Width="100"
                Content="Foo"
                Click="Button_Click" />
        <Button Width="100"
                Content="Bar"
                Click="Button_Click" />
        <Button Width="100"
                Content="Baz"
                Click="Button_Click" />
    </StackPanel>
    <ListBox Grid.Row="1"
             Name="TheList"
             Height="100" Width="{Binding ElementName=panel, Path=ActualWidth}" />
</Grid>

Here I bound width of ListBox to the actual width of panel with buttons, which in this case achieves what you want.

Upvotes: 1

Related Questions