rholek
rholek

Reputation: 340

WPF grid sizing Auto vs Star

In my XAML I have a certain amount of horizontal space. In it I need to put a text (of unknown length) followed by a button. Button should be placed directly after text. I am using following XAML:

<Border Name="Boundaries" MaxWidth="500" MinWidth="500" Height="20">
      <Grid>
         <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" TextTrimming="CharacterEllipsis">
                Lorem ipsum dolor sit amet, pri ex option legendos. Ludus solet at mel, facilisis urbanitas nam ad.
            </TextBlock>
         <Button Grid.Column="1">Button</Button>
     </Grid>
</Border>

Everything works fine when the text in TextBlock is short, however when text is long enough, TextBlock will overflow parent element and button will not be visible. To fix this I could set width of the first column definition to *, but this would mean that button is always on the right (even when text is single word, but I want it right after the text).

In past I fixed similar problems by setting MaxWidth of the first column definition trough converter from ActualSize of parent, however this is quite complicated and highly unreliable.

It would seem that such basic layout requirement would be a part of WPF, but I could not find anything. Am I missing something?

I want something like this: enter image description here

Upvotes: 4

Views: 2226

Answers (2)

Jon
Jon

Reputation: 2891

To do this without forcing a predetermined size you need to use the columns to get the layout size but don't use the columns for the actual layout. Add the two columns and then put a border in the first column that you can use to get the size for the TextBlock. In this example I bind the width of the second column to the width of the button, this way it will still work if you change the button text.

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="{Binding ElementName=mybutton, Path=ActualWidth}" />
        </Grid.ColumnDefinitions>
        <Border Grid.Column="0" Name="myborder"/>

        <StackPanel Orientation="Horizontal" Grid.ColumnSpan="2">
            <TextBlock MaxWidth="{Binding ElementName=myborder, Path=ActualWidth}" Text="test text" TextTrimming="CharacterEllipsis"/>
            <Button Name="mybutton" Content="button" />
        </StackPanel>
    </Grid>

Upvotes: 0

Chris Mack
Chris Mack

Reputation: 5208

You could use a DockPanel to achieve this. Something like:

<Border Name="Boundaries" MaxWidth="500" MinWidth="500" Height="20">
    <DockPanel HorizontalAlignment="Left" LastChildFill="False">
        <Button DockPanel.Dock="Right">Button</Button>
        <TextBlock DockPanel.Dock="Right" TextTrimming="CharacterEllipsis">
            Lorem ipsum dolor sit amet, pri ex option legendos. Ludus solet at mel, facilisis urbanitas nam ad.
        </TextBlock>
    </DockPanel>
</Border>

Upvotes: 4

Related Questions