WPF : Extend last column of ListView's GridView
Asked Answered
B

8

39

I have a ListView with a GridView with 3 columns. I want last column to take up remaining width of the ListView.

Balf answered 26/5, 2009 at 15:17 Comment(1)
Here's a great link that gets it right.Auer
J
27

That can't be done with simple XAML, but there are some solutions out there. Check this out:

Jaquelin answered 26/5, 2009 at 15:45 Comment(1)
The ListView Layout Manager link is exactly what I needed. Thank you for posting.Cordero
T
16

quick & dirty

xaml:

<ListView SizeChanged="ListView_SizeChanged" Loaded="ListView_Loaded" >
    <ListView.View>
        <GridView>
            <GridViewColumn Header="col1" Width="100" />
            <GridViewColumn Header="col1" Width="Auto" />
            <GridViewColumn Header="col1" />
        </GridView>
    </ListView.View>
</ListView>

cs:

private void ListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
    UpdateColumnsWidth(sender as ListView);
}

private void ListView_Loaded(object sender, RoutedEventArgs e)
{
    UpdateColumnsWidth(sender as ListView);
}

private void UpdateColumnsWidth(ListView listView)
{
    int autoFillColumnIndex = (listView.View as GridView).Columns.Count - 1;
    if (listView.ActualWidth == Double.NaN)
        listView.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
    double remainingSpace = listView.ActualWidth;
    for (int i = 0; i < (listView.View as GridView).Columns.Count; i++)
        if (i != autoFillColumnIndex)
            remainingSpace -= (listView.View as GridView).Columns[i].ActualWidth;
    (listView.View as GridView).Columns[autoFillColumnIndex].Width = remainingSpace >= 0 ? remainingSpace : 0;
}
Tercel answered 11/3, 2013 at 10:54 Comment(2)
Ignores scrollbar looks like.Bukavu
@Krythic thats not a super great reason for a downvote.Interspace
I
8

There is a way to do it using behavior pattern

<ListView HorizontalAlignment="Stretch"
          Behaviours:GridViewColumnResize.Enabled="True">
        <ListViewItem></ListViewItem>
        <ListView.View>
            <GridView>
                <GridViewColumn  Header="Column *"
                                   Behaviours:GridViewColumnResize.Width="*" >
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox HorizontalAlignment="Stretch" Text="Example1" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>

See the following link for some examples and link to read more http://lazycowprojects.tumblr.com/post/7063214400/wpf-c-listview-column-width-auto

And to see the source code. Check out https://github.com/rolfwessels/lazycowprojects/tree/master/Wpf

Immethodical answered 30/6, 2011 at 2:28 Comment(3)
"Behaviours:GridViewColumnResize.Width" and "Behaviours:GridViewColumnResize.Enabled" does not exist in WPF; are you using a third party framework? It would have been useful to mention that. Downvoting for now until your answer is fixed/updated.Filar
@Filar it think you might have missed the section that I explain that you need to add some source code.. They are called behaviours ...is part of wpf. See the github link, Add that to your source code.Immethodical
Hmm, I wrote that in 2011, I don't really do WPF anymore, but I would imagine this problem to be solved already.Immethodical
S
6

How About Using a Style

<Style x:Key="GridViewExtraStyle" TargetType="{x:Type GridViewColumnHeader}">
    <Setter Property="Background" Value="{x:Null}"/>
    <Setter Property="Foreground" Value="{x:Null}"/>
    <Setter Property="BorderBrush" Value="{x:Null}"/>
    <Setter Property="Width" Value="1000"/>
</Style>

<ListView>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Abc"/>
            <GridViewColumn Header="" HeaderContainerStyle="{DynamicResource GridViewExtraStyle}"/>
        </GridView>
    </ListView.View>
</ListView>
Stadiometer answered 15/7, 2014 at 20:53 Comment(2)
This is the best answer I've seen. Simple & effective.Haemic
Unfortunately, you now have a long horizontal scrollbar to deal withBanwell
N
0

I haven't seen a one-line/simple XAML only solution. Set a width that's appropriate for the design view, and then modify the width on window size change like this:

Private Sub winMain_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles Me.SizeChanged
    TryCast(lvwDownload.View, GridView).Columns(3).Width = lvwDownload.ActualWidth - 340
End Sub

NOTE: This logic does not change/hover the width of a column when another is resized. It's great for filling a listview with the last column.

Newmarket answered 26/3, 2016 at 0:43 Comment(1)
This worked for me, but I called it on the Loaded event as well as SizeChanged, and had to allow a small margin to prevent a scroll bar appearing. gridView.Columns[1].Width = listView.ActualWidth - gridView.Columns[0].ActualWidth - 10Gratulation
S
-1

A XAML-only alternative: create a hidden Grid of the same size, do all sizing on it, and bind GridView Width to the ActualWidth of individual Grid columns.

For example, I'd like a 3-column grid; the first column has a fixed-size checkbox, the other 2 split the available space 1:4.

    <Grid Visibility="Hidden" Grid.Row="2">
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Uid="ColumnDefinition_1" Width="27" />
            <ColumnDefinition x:Uid="ColumnDefinition_2" Width="*" />
            <ColumnDefinition x:Uid="ColumnDefinition_3" Width="3*" />
        </Grid.ColumnDefinitions>
        <Grid x:Uid="col0" Grid.Column="0" x:Name="col0"/>
        <Grid x:Uid="col1" Grid.Column="1" x:Name="col1"/>
        <Grid x:Uid="col2" Grid.Column="2" x:Name="col2"/>
    </Grid>

Then you can bind the Width like so:

      <GridViewColumn DisplayMemberBinding="{Binding Name}" 
                      Header="First Name" 
                      Width="{Binding ElementName=col1, Path=ActualWidth}" />

Some extra fiddling may be needed, to account for margins and borders, but this is a quick and dirty (if not necessarily elegant) way of formatting the length of GridView columns.

Sturm answered 18/5, 2021 at 14:56 Comment(0)
D
-3

I used Pale Ales's suggestion with a minor change:

<Style x:Key="GridViewExtraStyle" TargetType="{x:Type GridViewColumnHeader}">
    <Setter Property="Background" Value="{x:Null}"/>
    <Setter Property="Foreground" Value="{x:Null}"/>
    <Setter Property="BorderBrush" Value="{x:Null}"/>
</Style>

<ListView>
    <ListView.View>
        <GridView ColumnHeaderContainerStyle="{DynamicResource GridViewExtraStyle}">
            <GridViewColumn Header="Abc" Width="{Binding Path=mywidth}"/>
        </GridView>
    </ListView.View>
</ListView>
Dulce answered 23/7, 2014 at 15:36 Comment(0)
P
-3

You cannot be remove last column but you can be doin little illusion.

            <ControlTemplate TargetType="GridViewColumnHeader">
                <Grid>
                    <ContentPresenter x:Name="HeaderContent"
                                          Content="{TemplateBinding Content}" ... />
                    <Thumb x:Name="PART_HeaderGripper" ... />
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="HasContent"
                             Value="false">
                        <Setter Property="Visibility"
                                Value="Collapsed"
                                TargetName="PART_HeaderGripper" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
Peele answered 30/5, 2015 at 16:45 Comment(1)
The OP doesn't want to hide the last column, they want to extend it to fill the remaining widthDivorce

© 2022 - 2024 — McMap. All rights reserved.