ListView column auto sizing

心不动则不痛 提交于 2019-11-28 03:09:27

问题


Let's say I have the following ListView:

<ListView ScrollViewer.VerticalScrollBarVisibility="Auto">
  <ListView.View>
    <GridView>
      <GridViewColumn Header="Something" 
                      DisplayMemberBinding="{Binding Path=ShortText}" />
      <GridViewColumn Header="Description"
                      DisplayMemberBinding="{Binding Path=VeryLongTextWithCRs}" />
      <GridViewColumn Header="Something Else" 
                      DisplayMemberBinding="{Binding Path=AnotherShortText}" />
    </GridView>
  </ListView.View>
</ListView>

I'd like the short text columns to always fit in the screen, and the long text column to use the remaining space, word-wrapping if necessary.

Is that possible?


回答1:


There is no easy way to do this with a GridListView since it doesn't support setting the width of a column to "*" (fill remaining space).

Here is a discussion of how you could fake it by using an IValueConverter to set the width of the column to TotalListWidth - SumOfColumnWidths

On the other hand, have you considered using a DataGrid instead? This will support the kind of layout you are looking for, though is a considerably heavier control. It is also only native in .NET 4 - though you can get an equivalent for 3.5 through the WPF Toolkit.




回答2:


Follow this link: http://www.codeproject.com/KB/grid/ListView_layout_manager.aspx Its work for me :)




回答3:


Set Width="Auto" on your GridViewColumns. However, due to virtualization you may encounter some problems with auto-sizing.

See this question.

So, long-story-short, if you want accurate auto-sizing of columns you'll need to recalculate your widths when the visible data changes, due to virtualization.




回答4:


<Grid Name="dummygrid" Visibility="Hidden">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.5*"></ColumnDefinition>
                <ColumnDefinition Width="0.2*"></ColumnDefinition>
                <ColumnDefinition Width="0.1*"></ColumnDefinition>
                <ColumnDefinition Width="0.2*"></ColumnDefinition>
                <ColumnDefinition Width="150"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Border Grid.Column="0" Name="dummywidth1"></Border>
            <Border Grid.Column="1" Name="dummywidth2"></Border>
            <Border Grid.Column="2" Name="dummywidth3"></Border>
            <Border Grid.Column="3" Name="dummywidth4"></Border>
            <Border Grid.Column="5" Name="dummywidth5"></Border>
        </Grid>
        <ListView  Name="Installer_LV" Grid.Row="1" ItemContainerStyle="{StaticResource LV_ItemStyle}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"  AlternationCount="2">
            <ListView.View>
                <GridView ColumnHeaderContainerStyle="{StaticResource LV_HeaderStyle}">
                    <GridViewColumn  Width="{Binding ElementName=dummywidth1, Path=ActualWidth}"  DisplayMemberBinding="{Binding DisplayName}" >
                        <GridViewColumn.Header>
                            <GridViewColumnHeader Tag="DisplayName" Click="InstallerLV_HeaderClick">Name</GridViewColumnHeader>
                        </GridViewColumn.Header>
                    </GridViewColumn>
                    <GridViewColumn  Width="{Binding ElementName=dummywidth2, Path=ActualWidth}" DisplayMemberBinding="{Binding Publisher}">
                        <GridViewColumn.Header>
                            <GridViewColumnHeader Tag="Publisher" Click="InstallerLV_HeaderClick">Publisher</GridViewColumnHeader>
                        </GridViewColumn.Header>
                    </GridViewColumn>
                    <GridViewColumn  Width="{Binding ElementName=dummywidth3, Path=ActualWidth}" DisplayMemberBinding="{Binding Version}">
                        <GridViewColumn.Header>
                            <GridViewColumnHeader Tag="Version" Click="InstallerLV_HeaderClick">Version</GridViewColumnHeader>
                        </GridViewColumn.Header>
                    </GridViewColumn>
                    <GridViewColumn  Width="{Binding ElementName=dummywidth4, Path=ActualWidth}" DisplayMemberBinding="{Binding Size}">
                        <GridViewColumn.Header>
                            <GridViewColumnHeader Tag="Size" Click="InstallerLV_HeaderClick">Size</GridViewColumnHeader>
                        </GridViewColumn.Header>
                    </GridViewColumn>
                    <GridViewColumn Header="Action" Width="150">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Button  Height="38" Width="130" Style="{DynamicResource RoundedButton}" Content="{Binding Status}" Tag="{Binding ModuleId}"  HorizontalAlignment="Center" VerticalAlignment="Center" Click="onActionClick"></Button>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>

In the above example i have used a dummy grid and split into 5 columns and using binding assign that size to "GridViewColum" by

Width="{Binding ElementName=dummywidth4, Path=ActualWidth}"

So that when the hidden dummy grid column size changes it will get reflect in gridview column size also.




回答5:


This works for me, toggling the Width to ActualWidth and then back to NaN for any columns that don't have widths explicitly set. This will only work if the listview columns do not contain controls. I usually call this after data in the list has changed.

Public Shared Sub AutoResizeListView(lst As Windows.Controls.ListView)
    Dim gv = DirectCast(lst.View, Windows.Controls.GridView)
    For Each gvc In gv.Columns
        If Double.IsNaN(gvc.Width) Then
            gvc.Width = gvc.ActualWidth
            gvc.Width = Double.NaN
        End If
    Next
End Sub



回答6:


First set the name in the column header like so:

<GridViewColumn Header="Description" Width="350" x:Name="lvhDescription"/>

And then on resize modify width.

Private Sub winMain_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles Me.SizeChanged


    If Me.IsLoaded = False Then Exit Sub

    lvhDescription.Width = e.NewSize.Width - 665


End Sub



回答7:


I'd like to present an another approach in order to size each column with the largest element width. Do this following on each list view item with the help of a loop.

No need to change size after a re-size window event.

Leaves UnitWidth as the constant font width size.

You can also define a delegate to the SourceUpdated event.

GridView gv = (myListView.View as GridView);
if (titleLen < c.Title.Length)
{
    titleLen = c.Title.Length;
    gv.Columns[0].Width = titleLen * UnitWidth;
}
if (cssLen < c.CSSName.Length)
{
    cssLen = c.CSSName.Length;
    gv.Columns[1].Width = cssLen * UnitWidth;
}
if (valueLen < c.Value.Length)
{
    valueLen = c.Value.Length;
    gv.Columns[2].Width = valueLen * UnitWidth;
}



回答8:


Try this code instead,

  private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        double remainingSpace = mylistviewname.ActualWidth;

        if (remainingSpace > 0)
        {

            (mylistviewname.View as GridView).Columns[1].Width = Math.Ceiling(remainingSpace / 3);
            (mylistviewname.View as GridView).Columns[2].Width = Math.Ceiling(remainingSpace / 3);
            (mylistviewname.View as GridView).Columns[3].Width = Math.Ceiling(remainingSpace / 3);
        }
    }

Here i user SizeChanged event so when the windows size change this function is triggered and update the width of the listviewheader. I have 3 listviewheaders so divided by 3 if you have more than 3 divide by appropriate value.




回答9:


<ListView ScrollViewer.VerticalScrollBarVisibility="Auto" Name="someList">
  <ListView.View>
    <GridView>
      <GridViewColumn Width={Binding ElementName=someList, Path=ActualWidth/3} Header="Something" DisplayMemberBinding="{Binding Path=ShortText}" />
      <GridViewColumn  Width={Binding ElementName=someList, Path=ActualWidth/3} Header="Description" DisplayMemberBinding="{Binding Path=VeryLongTextWithCRs}" />
      <GridViewColumn  Width={Binding ElementName=someList, Path=ActualWidth/3} Header="Something Else" DisplayMemberBinding="{Binding Path=AnotherShortText}" />
    </GridView>
  </ListView.View>
</ListView>


来源:https://stackoverflow.com/questions/2834971/listview-column-auto-sizing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!