user2357446
user2357446

Reputation: 676

Always keep column width's equal in WPF

I current have a WPF application that contains a ListBox of Grid items.

These grids have 2 columns each and the first column contains text and the second one contains an ellipse.

My issue is that I currently have both ColumnDefinition set to have width of .5* so they each take 50% of the total width. However, this doesn't work when the text is too long or else it pushes the ellipse in the second column out of line with the rest of the ellipses in the list (looking vertically from top to bottom).

Basically this is what I get:

enter image description here

What I would like to happen is have all of the elipses in-line no matter how long the text in the first column is.

I've tried placing the first column's text inside of a ViewBox to auto-size it but that doesn't seem to work either.

Here is the full XAML for the DataTemplate:

<Grid x:Name="MainTermServListGrid">
    <Grid.RowDefinitions>
        <RowDefinition x:Name="MainTermServMainRow"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Column="0" Text="{Binding TServer}" FontSize="15" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    <Grid x:Name="OldPathGrid" Grid.Column="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width=".5*"/>
            <ColumnDefinition Width=".5*"/>
        </Grid.ColumnDefinitions>
        <Viewbox Grid.Column="0" Stretch="Uniform">
            <TextBlock Grid.Column="0">
            <Run Text="Path: "/>
            <Run Text="{Binding OldPath}"/>
            </TextBlock>
        </Viewbox>

        <Ellipse Grid.Column="1" HorizontalAlignment="Center" Width="{Binding ElementName=MainTermServListGrid, Path=ActualHeight}" Fill="{Binding IsOldPathValid, Converter={StaticResource ValPthToBgClr}}"/>
    </Grid>
    <Grid x:Name="NewPathGrid" Grid.Column="2">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width=".5*"/>
            <ColumnDefinition Width=".5*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0">
            <Run Text="Path: "/>
            <Run Text="{Binding NewPath}"/>
        </TextBlock>
        <Ellipse Grid.Column="1" Width="{Binding ElementName=MainTermServListGrid, Path=ActualHeight}" Fill="{Binding IsNewPathValid, Converter={StaticResource ValPthToBgClr}}"/>
    </Grid>
</Grid>

Upvotes: 0

Views: 196

Answers (1)

Clint
Clint

Reputation: 6220

You should take a look at SharedSizeGroup

Essentially:

<ItemsControl ItemsSource="{Binding SomeItems}"
   Grid.IsSharedSizeScope="True">
   <ItemsControl.ItemTemplate>
     <Grid>
       <Grid.ColumnDefinitions>
         <ColumnDefinition SharedSizeGroup="ColA" Width=".5*" />
       </Grid.ColumnDefinitions>
     </Grid>
   </ItemsControl.ItemTemplate>
</ItemsControl>

Using the SharedSizeScope and SharedSizeGroup, you can ensure columns / rows are the same size across different grids within the same containing scope

NOTE: It doesn't have to be an ItemsControl any container using the attached property Grid.IsSharedSizeScope will ensure that grids contained within will pay attention.

Upvotes: 2

Related Questions