Search code examples
wpfdata-bindinggridviewdatagridviewcolumn

WPF. Bind to height of cell in GridViewColumn?


I've a GridView defined like this:

            <ListView x:Name="colorLegend" Background="Transparent" ItemsSource="{Binding /Colors}">
            <ListView.Resources>
                <Style x:Key="myHeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
                    <Setter Property="Visibility" Value="Collapsed" />
                </Style>
            </ListView.Resources>
            <ListView.View>
                <GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
                    <GridViewColumn Header="Image" Width="100">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Border Background="{Binding Brush}" Height="20" Width="40" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Width="auto" />
                </GridView>
            </ListView.View>
        </ListView>

I want the height of the border inside the first cell to be as high as the height of the cell column. Can I bind the height of the border to the height of the second cell?

What I want is to be able to change the fontsize for the second cell and the border in first to resize to match the change?

Thanks!


Solution

  • instead on using the Height, I would rather use VerticalAlignment=Stretch in this case:

    <DataTemplate>
        <Border Background="{Binding Brush}" VerticalAlignment="Stretch" Width="40" />
    </DataTemplate>
    

    this should do the trick

    (you might also need a MinHeight in this case, just for safety)

    NB: it's a common gotcha that the VerticalAlignment property can also be used to set an equivalent of Height=* in such cases where you want the height to simply fill the space you have, but are not able to bind it to anything. VerticalALignment=Stretch or HorizontalAlignment=Stretch is actually very useful, though not very well known, sadly.

    edit: if this does not work, you might want to try binding to the parent like this:

    <DataTemplate>
        <Border Height="{Binding ActualHeight, RelativeSource={RelativeSource AncestorLevel=1}}" Background="{Binding Brush}" Width="40" />
    </DataTemplate>
    

    (Disclaimer: I did not try this in a GridViewColumn's CellTemplate, so don't shoot me if it does not work)

    edit 2: if nothing above works, try intercalating a Grid or a Panel in your Template, so that it inherits the height an can forward it to the Border. (AFAIK, Grid and Panels do not behave like borders as far as Measure inheritance is concerned):

    <DataTemplate>
        <Grid>
            <Border Background="{Binding Brush}" VerticalAlignment="Stretch" Width="40" />
        </Grid>
    </DataTemplate>
    

    or:

    <DataTemplate>
        <Grid Name="grid" VerticalAlignment="Stretch">
            <Border Background="{Binding Brush}" Width="40" Height="{Binding ActualHeight ElementName=grid}" />
        </Grid>
    </DataTemplate>