ListView列自动调整大小

15

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

我希望短文本列始终适合屏幕,并且长文本列使用剩余的空间,必要时进行单词换行。

这种情况是否可能?

8个回答

8

使用GridListView没有简单的方法来设置列宽为“*”(填充剩余空间),因此这个需求比较麻烦。

这里有一个讨论,介绍了如何通过使用IValueConverter来模拟实现将某一列的宽度设置为TotalListWidth - SumOfColumnWidths的效果。

另外,您是否考虑使用DataGrid控件? 这个控件支持您想要的布局方式,但是它的控制权更重。同时,它只是在.NET 4中本地支持的,但您可以通过WPF Toolkit获得相当于.NET 3.5版本的控件。


Martin,使用IValueConverter解决方案的问题在于它需要设置所有其他宽度(我宁愿不设置任何宽度)。目前为止,我不能更改此项目中的ListViews,但我下一个项目肯定会使用DataGrid。谢谢! - Diego Mijelshon
18
尽可能避免使用数据网格!它很糟糕且充满漏洞。 - Orion Edwards

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

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

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

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

6

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

看看这个问题。

简而言之,如果你想要准确的列自动调整大小,你需要在可见数据更改时重新计算宽度,因为存在虚拟化。


默认不是自适应吗?问题是,它似乎会创建水平滚动条,因为它会扩展到超出可用空间。 - Diego Mijelshon

3

这对我很有用,将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

1

首先,像这样在列标题中设置名称:

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

然后在调整大小时修改宽度。

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

0

请尝试使用这段代码替代原来的代码:

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

在这里我使用了SizeChanged事件,所以当窗口大小改变时,该函数会被触发并更新listviewheader的宽度。我有3个listviewheaders,所以除以3,如果你有更多的话,就根据适当的值进行除法运算。


0

我想提出另一种方法来确定每个列的最大元素宽度。

在循环的帮助下,对每个列表视图项执行以下操作。

无需在重新调整窗口大小后更改大小。

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

您还可以定义一个委托来处理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;
}

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接