Автоматическое определение столбца 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>
Я бы хотел, чтобы короткие текстовые столбцы всегда вписывались в экран, а длинный текстовый столбец использовал оставшееся пространство, при необходимости обертывая слово.
Возможно ли это?
Ответы
Ответ 1
Нет простого способа сделать это с помощью GridListView, поскольку он не поддерживает установку ширины столбца на "*" (заполнение оставшегося пространства).
Здесь обсуждается, как вы могли подделать его, используя IValueConverter, чтобы установить ширину столбца в TotalListWidth - SumOfColumnWidths
С другой стороны, рассмотрели ли вы вместо этого DataGrid? Это будет поддерживать вид макета, который вы ищете, но значительно более жесткий контроль. Он также является только родным в .NET 4 - хотя вы можете получить эквивалент для 3.5 через WPF Toolkit.
Ответ 2
Перейдите по этой ссылке: http://www.codeproject.com/KB/grid/ListView_layout_manager.aspx
Его работа для меня:)
Ответ 3
<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 столбцов и используя привязку присваивал этот размер "GridViewColum"
Width = "{Binding ElementName = dummywidth4, Path = ActualWidth}"
Таким образом, при изменении размера столбца скрытого фиктивного сетки он также получит отражение в размере столбца gridview.
Ответ 4
Установите Width="Auto"
на свои GridViewColumns. Однако из-за виртуализации вы можете столкнуться с некоторыми проблемами с автоматическим калибровкой.
См. этот вопрос.
Итак, длинный рассказ, если вам нужна точная автоматическая сортировка столбцов, вам нужно будет пересчитать свою ширину, когда видимые данные меняются из-за виртуализации.
Ответ 5
Это работает для меня, переключая Width
на ActualWidth
, а затем обратно на NaN
для любых столбцов, которые явно не имеют ширины. Это будет работать, только если столбцы listview не содержат элементов управления. Обычно я вызываю это после изменения данных в списке.
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
Я хотел бы представить другой подход, чтобы отсортировать каждый столбец с наибольшей шириной элемента.
Сделайте следующее для каждого элемента списка с помощью цикла.
Не нужно изменять размер после события окна изменения размера.
Листья 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;
}
Ответ 7
Попробуйте использовать этот код,
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);
}
}
Здесь я user SizeChanged, поэтому, когда размер окна изменяется, эта функция запускается и обновляет ширину listviewheader. У меня есть 3 списка, которые разделены на 3, если у вас более 3 делений на соответствующее значение.
Ответ 8
Сначала установите имя в заголовке столбца следующим образом:
<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
Ответ 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>