wpf ListView 列自动调整大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2834971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:46:04  来源:igfitidea点击:

ListView column auto sizing

wpflistviewautosize

提问by Diego Mijelshon

Let's say I have the following ListView:

假设我有以下 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?

那可能吗?

采纳答案by Martin Harris

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).

使用 GridListView 没有简单的方法可以做到这一点,因为它不支持将列的宽度设置为“*”(填充剩余空间)。

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

是关于如何通过使用 IValueConverter 将列的宽度设置为 TotalListWidth - SumOfColumnWidths 来伪造它的讨论

On the other hand, have you considered using a DataGridinstead? 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.

另一方面,您是否考虑过使用DataGrid代替?这将支持您正在寻找的布局类型,尽管是一个相当重的控件。它也仅在 .NET 4 中是本机的 - 尽管您可以通过WPF Toolkit获得 3.5 的等效项。

回答by Doug

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

Width="Auto"在您的 GridViewColumns 上设置。但是,由于虚拟化,您可能会遇到一些自动调整大小的问题。

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.

因此,长话短说,如果您想要准确地自动调整列的大小,由于虚拟化,您需要在可见数据发生变化时重新计算宽度。

回答by Joee

<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

在上面的例子中,我使用了一个虚拟网格并分成 5 列,并使用绑定将该大小分配给“GridViewColum”

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

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.

因此,当隐藏的虚拟网格列大小更改时,它也会反映在 gridview 列大小中。

回答by GeoFrias

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

回答by Carter Medlin

This works for me, toggling the Widthto ActualWidthand then back to NaNfor 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.

这对我有用,Width为没有明确设置宽度的任何列切换到ActualWidth然后返回到NaN。这仅在列表视图列不包含控件时才有效。我通常在列表中的数据更改后调用它。

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

回答by user4349921

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 UnitWidthas the constant font width size.

UnitWidth 保留为常量字体宽度大小。

You can also define a delegate to the SourceUpdated event.

您还可以定义 SourceUpdated 事件的委托。

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;
}

回答by Ravi Ranjan

<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>

回答by Joee

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.

在这里,我使用 SizeChanged 事件,因此当窗口大小更改时,会触发此功能并更新 listviewheader 的宽度。我有 3 个 listviewheaders,如果你有超过 3 个除以适当的值,那么除以 3。