如何自动化和正确alignmentWPF中的GridViewColumn数据?

我怎么能够:

  • 右alignmentID列中的文本
  • 根据具有最长可见数据的单元格的文本长度,使每列自动resize?

这里是代码:

<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“集合”更新列长度较长的数据,列大小不会自我更新,这只是一个解决scheme数据的初始显示:

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

要使每个列自动resize,可以在GridViewColumn上设置Width =“Auto”。

要将ID列中的文本右alignment,可以使用TextBlock创build单元格模板并设置TextAlignment。 然后设置ListViewItem.Horizo​​ntalContentAlignment(在ListViewItem上使用setter的样式),使单元格模板填充整个GridViewCell。

也许有一个更简单的解决scheme,但这应该工作。

注意:该解决scheme需要在CellTemplate中的Horizo​​ntalContentAlignment = Stretch in Window.Resources和TextAlignment = Right

 <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也在重新resize,那么你可以使用一个行为模式重新调整列的大小以适应完整的ListView宽度。 与使用grid.column定义几乎相同

 <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

由于我有一个ItemContainerStyle我不得不把Horizo​​ntalContentAlignment放在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" /> .... 

我已经创build了以下类,并在所需的任何地方用于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); } } 

我喜欢user1333423的解决scheme,除了它总是重新确定每一列的大小, 我需要允许一些列固定宽度。 因此,在这个版本中,宽度设置为“自动”的列将被自动resize,而设置为固定值的列将不会自动resize。

 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的宽度。 宽度= 100是默认宽度,直到第一次resize。 没有任何代码在后面。 一切都在XAML。

我接受的答案有问题(因为我错过了Horizo​​ntalAlignment = Stretch部分,并调整了原来的答案)。

这是另一种技术。 它使用具有SharedSizeGroup的网格。

注意: ListView上的Grid.IsSharedScope = true

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

我创build了一个用于更新列表的GridView列标题的函数,并在窗口重新resize或列表视图更新其布局时调用它。

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