Как авторазмер и выравнивание по правому краю данных GridViewColumn в WPF?
Как я могу:
- выравнивание текста по правому краю в столбце ID
- сделать каждый из столбцов автоматического размера в соответствии с длиной текста ячейки с самыми длинными видимыми данными?
вот код:
<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}" Width="40"/>
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="100" />
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}"/>
</GridView>
</ListView.View>
</ListView>
частичный ответ:
спасибо Kjetil, GridViewColumn.CellTemplate работает хорошо, и автоматическая ширина работает, конечно, но когда ObservativeCollection "коллекция" обновляется с более длинной, чем ширина столбца данные, размеры столбцов не обновляются, так что это только решение для первоначального отображения данных:
<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Id}" TextAlignment="Right" Width="40"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="Auto" />
<GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="Auto"/>
</GridView>
</ListView.View>
</ListView>
9 ответов:
чтобы сделать каждый из столбцов autosize вы можете установить Width="Auto" на GridViewColumn.
чтобы выровнять текст справа в столбце ID, вы можете создать шаблон ячейки с помощью TextBlock и установить TextAlignment. Затем установите ListViewItem.HorizontalContentAlignment (используя стиль с сеттером на ListViewItem), чтобы сделать шаблон ячейки заполнить всю GridViewCell.
может есть более простое решение, но это должно работа.
Примечание: решение требует как HorizontalContentAlignment=Stretch в окно.Ресурсы и TextAlignment=Right в CellTemplate.
<Window x:Class="WpfApplication6.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Window.Resources> <Style TargetType="ListViewItem"> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> </Style> </Window.Resources> <Grid> <ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}"> <ListView.View> <GridView> <GridViewColumn Header="ID" Width="40"> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Id}" TextAlignment="Right" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="Auto" /> <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="Auto"/> </GridView> </ListView.View> </ListView> </Grid> </Window>
Если ширина содержимого изменяется, вам придется использовать этот бит кода для обновления каждого столбца:
private void ResizeGridViewColumn(GridViewColumn column) { if (double.IsNaN(column.Width)) { column.Width = column.ActualWidth; } column.Width = double.NaN; }
вам придется запускать его каждый раз, когда данные для этого столбца обновляются.
Если ваш listview также изменяет размер, вы можете использовать шаблон поведения для изменения размера столбцов в соответствии с полной шириной ListView. Почти так же, как вы используете сетку.определения столбцов
<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>
см. следующую ссылку для некоторых примеров и ссылку на исходный код http://lazycowprojects.tumblr.com/post/7063214400/wpf-c-listview-column-width-auto
Я создал следующий класс и используется во всем приложении, где требуется вместо
GridView
:/// <summary> /// Represents a view mode that displays data items in columns for a System.Windows.Controls.ListView control with auto sized columns based on the column content /// </summary> public class AutoSizedGridView : GridView { protected override void PrepareItem(ListViewItem item) { foreach (GridViewColumn column in Columns) { // Setting NaN for the column width automatically determines the required // width enough to hold the content completely. // If the width is NaN, first set it to ActualWidth temporarily. if (double.IsNaN(column.Width)) column.Width = column.ActualWidth; // Finally, set the column with to NaN. This raises the property change // event and re computes the width. column.Width = double.NaN; } base.PrepareItem(item); } }
поскольку у меня был ItemContainerStyle, мне пришлось поместить HorizontalContentAlignment в ItemContainerStyle
<ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Style.Triggers> <DataTrigger Binding="{Binding Path=FieldDef.DispDetail, Mode=OneWay}" Value="False"> <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> </Style.Triggers> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> ....
Мне понравилось решение user1333423, за исключением того, что оно всегда изменяло размер каждого столбца; мне нужно было разрешить некоторым столбцам фиксированную ширину. Таким образом, в этой версии столбцы с шириной, установленной на "Auto", будут иметь автоматический размер, а те, которые установлены на фиксированную величину, не будут иметь автоматического размера.
public class AutoSizedGridView : GridView { HashSet<int> _autoWidthColumns; protected override void PrepareItem(ListViewItem item) { if (_autoWidthColumns == null) { _autoWidthColumns = new HashSet<int>(); foreach (var column in Columns) { if(double.IsNaN(column.Width)) _autoWidthColumns.Add(column.GetHashCode()); } } foreach (GridViewColumn column in Columns) { if (_autoWidthColumns.Contains(column.GetHashCode())) { if (double.IsNaN(column.Width)) column.Width = column.ActualWidth; column.Width = double.NaN; } } base.PrepareItem(item); } }
Я знаю, что это слишком поздно, но мой подход такой:
<GridViewColumn x:Name="GridHeaderLocalSize" Width="100"> <GridViewColumn.Header> <GridViewColumnHeader HorizontalContentAlignment="Right"> <Grid Width="Auto" HorizontalAlignment="Right"> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0" Text="Local size" TextAlignment="Right" Padding="0,0,5,0"/> </Grid> </GridViewColumnHeader> </GridViewColumn.Header> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock Width="{Binding ElementName=GridHeaderLocalSize, Path=Width, FallbackValue=100}" HorizontalAlignment="Right" TextAlignment="Right" Padding="0,0,5,0" Text="Text" > </TextBlock> </DataTemplate> </GridViewColumn.CellTemplate>
основная идея заключается в привязке ширины элемента cellTemplete к ширине столбца ViewGridColumn. Width=100-это ширина по умолчанию, используемая до первого изменения размера. Нет никакого кода. Все находится в xaml.
У меня были проблемы с принятым ответом (потому что я пропустил часть HorizontalAlignment=Stretch и скорректировал исходный ответ).
Это еще одна техника. Он использует сетку с SharedSizeGroup.
Примечание: the решетки.IsSharedScope=true на ListView.
<Window x:Class="WpfApplication6.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300"> <Grid> <ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}" Grid.IsSharedSizeScope="True"> <ListView.View> <GridView> <GridViewColumn Header="ID" Width="40"> <GridViewColumn.CellTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" SharedSizeGroup="IdColumn"/> </Grid.ColumnDefinitions> <TextBlock HorizontalAlignment="Right" Text={Binding Path=Id}"/> </Grid> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="Auto" /> <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="Auto"/> </GridView> </ListView.View> </ListView> </Grid> </Window>
Я создал функцию для обновления заголовков столбцов GridView для списка и вызываю ее всякий раз, когда окно изменяется или listview обновляет его макет.
public void correctColumnWidths() { double remainingSpace = myList.ActualWidth; if (remainingSpace > 0) { for (int i = 0; i < (myList.View as GridView).Columns.Count; i++) if (i != 2) remainingSpace -= (myList.View as GridView).Columns[i].ActualWidth; //Leave 15 px free for scrollbar remainingSpace -= 15; (myList.View as GridView).Columns[2].Width = remainingSpace; } }