我怎么能:
以下是代码:
<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“Collection”时,列大小不会自行更新,因此只有初始显示数据的解决方案:
<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>
答案 0 :(得分:97)
要使每个列自动调整大小,您可以在GridViewColumn上设置Width =“Auto”。
要右对齐ID列中的文本,可以使用TextBlock创建单元格模板并设置TextAlignment。然后设置ListViewItem.HorizontalContentAlignment(使用ListViewItem上带有setter的样式)使单元格模板填充整个GridViewCell。
也许有一个更简单的解决方案,但这应该有用。
注意:解决方案需要Window.Resources中的 HorizontalContentAlignment = Stretch 和CellTemplate中的 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>
答案 1 :(得分:33)
如果内容的宽度发生变化,您将不得不使用这段代码来更新每一列:
private void ResizeGridViewColumn(GridViewColumn column)
{
if (double.IsNaN(column.Width))
{
column.Width = column.ActualWidth;
}
column.Width = double.NaN;
}
每次该列的数据更新时,您都必须触发它。
答案 2 :(得分:17)
如果您的列表视图也在重新调整大小,那么您可以使用行为模式重新调整列的大小以适应完整的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
答案 3 :(得分:10)
我创建了以下类,并在需要的地方使用整个应用程序代替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);
}
}
答案 4 :(得分:7)
由于我有一个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" />
....
答案 5 :(得分:5)
我喜欢user1333423的解决方案,除了它总是重新调整每一列的大小;我需要允许一些列固定宽度。所以在这个版本中,宽度设置为&#34; Auto&#34;将自动调整大小,设置为固定数量的将不会自动调整大小。
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);
}
}
答案 6 :(得分:2)
我知道这太晚了,但这是我的方法:
<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是在第一次调整大小之前使用的默认宽度。背后没有任何代码。一切都在xaml。
答案 7 :(得分:1)
我对接受的答案有疑问(因为我错过了HorizontalAlignment = Stretch部分,并调整了原始答案)。
这是另一种技术。它使用带有SharedSizeGroup的Grid。
注意: 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>
答案 8 :(得分:1)
我创建了一个用于更新列表的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;
}
}
答案 9 :(得分:1)
@RandomEngy 上面给出的解决方案有效,但似乎有一个问题, 仅根据可见数据(因此,前 X 行)调整大小,不一定是每列的最长(最宽行)值。
要解决上述问题,可以执行以下操作。
添加更改过的集合,如下所示,
((INotifyCollectionChanged) MyListView.ItemsSource).CollectionChanged += CollectionChanged_Handler;
还要声明一个私有的 maxWidth 属性来存储您的视图遇到的最长内容。
private double maxWidth = 200;//Whatever your default width is.
现在处理程序如下,
private void CollectionChanged_Handler(object sender, NotifyCollectionChangedEventArgs args)
{
var gridView = (GridView)MyListView.View;
if(gridView != null)
{
foreach( var column in gridView.Columns)
{
if(column.ActualWidth > maxWidth)
{
if (double.IsNaN(column.Width))
{
maxWidth = column.ActualWidth;
column.Width = maxWidth ;
}
column.Width = double.NaN;
}
}
}
此外,一旦您启动对话框,寡妇可能已经填充了多行,而最上面的行不是最长的。仅当集合更改时才会触发上面的代码,但由于数据已经加载并且加载对话框时可见的行不是最宽的行,因此上面的代码将无法调整列的大小。为了解决这个问题,在 ListView_OnPreviewMouseLeftButton 事件上调用上面的处理程序。如下图,
private void MyListView_OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
CollectionChanged_Handler(sender, null);
}
一旦有人滚动到视图的最宽行内容,上述代码将刷新您的列宽。
答案 10 :(得分:0)
这是您的代码
<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>
尝试一下
<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Id}" Width="Auto">
<GridViewColumnHeader Content="ID" Width="Auto" />
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding FirstName}" Width="Auto">
<GridViewColumnHeader Content="First Name" Width="Auto" />
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding LastName}" Width="Auto">
<GridViewColumnHeader Content="Last Name" Width="Auto" />
</GridViewColumn
</GridView>
</ListView.View>
</ListView>
答案 11 :(得分:0)
嗯,我刚遇到这个问题,我用 IValueConverter 解决了它。
public class GridViewColumHeaderWidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (double)value / 8;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
注意:8 是 GridViewColumns 的数量
现在在 Xaml 中:
<ListView x:Name="TheListView" ItemsSource="{Binding Customers}">
<ListView.View>
<GridView>
<!-- Id -->
<GridViewColumn Width="{Binding ElementName=TheListView, Path=ActualWidth, Converter={StaticResource GridViewColumHeaderWidthConverter}}">
<GridViewColumnHeader Content="Id" />
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding CustomerId}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!-- Code -->
<GridViewColumn Width="{Binding ElementName=TheListView, Path=ActualWidth, Converter={StaticResource GridViewColumHeaderWidthConverter}}">
<GridViewColumnHeader Content="Code" />
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding CustomerCode}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
不要忘记包含转换器文件。在这种情况下,我在 App.xaml 中定义了转换器
<Application.Resources>
<converters:GridViewColumHeaderWidthConverter x:Key="GridViewColumHeaderWidthConverter" />
</Application.Resources>