GridViewColumn Resize doesn't work with UserControl

16 Views Asked by At

I have a WPF ListView which uses GridViewColumns for its various columns.

<ListView Name="LvArticles"  Grid.Column="0" Grid.Row="3"  MinWidth="800" ItemsSource="{Binding SearchResults}" SelectedItem="{Binding SearchResultsSelectedItem}" IsSynchronizedWithCurrentItem="True" Margin="3">
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn Header="Distance" DisplayMemberBinding="{Binding Distance}"></GridViewColumn>
                <GridViewColumn Header="Ident" DisplayMemberBinding="{Binding Article.Ident}"></GridViewColumn>
                <GridViewColumn Header="Beschreibung">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate DataType="{x:Type models:ArticleSearchResult}">
                            <helpers:FormattedTextControl Text="{Binding Article.DescriptionLong2}" HighlightText="{Binding OriginalMpn}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"  />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <!--<GridViewColumn Header="Beschreibung" DisplayMemberBinding="{Binding Article.DescriptionLong2}"></GridViewColumn>-->
            </GridView.Columns>
        </GridView>
    </ListView.View>
</ListView>

As you can see, for debugging I have to GridViewColumns (one is currently commented out) which display the Text Article.DescriptionLong2.

Whenever the resultset changes, I perform a resize of all the columns using the code:

c.Width = 0; //set it to no width
c.Width = double.NaN; //resize it automatically

This works as long as I am using the DisplayMemberBinding line.

Now I have a custom user control which is basically built like this

<UserControl x:Class="GrafBomBuilder.Helpers.FormattedTextControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800" >
    <Grid Name="Stack" HorizontalAlignment="Stretch">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" Text="{Binding Part1}" />
        <TextBlock Grid.Column="1" Text="{Binding Part2}" Foreground="Red" />
        <TextBlock Grid.Column="2" Text="{Binding Part3}" />
    </Grid>    

</UserControl>

If I use the user control instead of the DisplayMemberBinding (which in turn should only be a TextBlock) the column is resized to the header width, not to the width of the content. It appears as if the content was 0 although it's there.

I have a feeling that I need to somewhow calculate the actual size of the user control before I resize the column?

Is that correct? How would I do that? Is there anything I'm missing?

1

There are 1 best solutions below

0
Tom L. On

It seems that the Visual Container was not generated previous to re-sizing the controls. I have changed the code to the following and now it works as expected.

foreach (var item in LvArticles.Items)
{
    object viewItem = LvArticles.ItemContainerGenerator.ContainerFromItem(item);
    if (viewItem == null)
    {
        LvArticles.UpdateLayout();
        LvArticles.ItemContainerGenerator.ContainerFromItem(item);
    }
}

foreach (GridViewColumn c in ((GridView)LvArticles.View).Columns)
{
    c.Width = 0; //set it to no width
    c.Width = double.NaN; //resize it automatically
}

If I understand correctly, this forces the UI to generate the actual representation. Once the representation exists, we can calculate the column sized successfully.