如何在WPF中自动调整GridViewColumn数据的大小并右对齐?
我怎样才能:如何在WPF中自动调整GridViewColumn数据的大小并右对齐?,wpf,xaml,listview,gridview,gridviewcolumn,Wpf,Xaml,Listview,Gridview,Gridviewcolumn,我怎样才能: 右对齐ID列中的文本 是否根据具有最长可见数据的单元格的文本长度自动调整每个列的大小 代码如下: <ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}"> <ListView.View> <GridView> <GridViewColumn Header="ID" DisplayMemberBinding=
- 右对齐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“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>
要使每列自动调整大小,可以在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>
如果内容的宽度发生变化,则必须使用此代码位来更新每一列:
private void ResizeGridViewColumn(GridViewColumn column)
{
if (double.IsNaN(column.Width))
{
column.Width = column.ActualWidth;
}
column.Width = double.NaN;
}
每次该列的数据更新时,您都必须触发它。我对接受的答案有问题(因为我错过了HorizontalAlignment=Stretch部分,并调整了原始答案) 这是另一种技术。它使用带有SharedSizeGroup的网格 注意:列表视图上的网格。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>
如果listview也在重新调整大小,则可以使用行为模式来重新调整列的大小,以适应完整的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>
有关一些示例和源代码的链接,请参见以下链接
因为我有一个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" />
....
....
我创建了以下类,并在需要时在应用程序中使用它来代替GridView
:
//
///表示一种视图模式,该模式在System.Windows.Controls.ListView控件的列中显示数据项,并根据列内容自动调整列的大小
///
公共类AutoSizedGridView:GridView
{
受保护的覆盖无效准备项(ListViewItem)
{
foreach(列中的GridViewColumn列)
{
//为列宽设置NaN将自动确定所需的
//宽度足以完全容纳内容。
//如果宽度为NaN,首先将其临时设置为ActualWidth。
if(double.IsNaN(列宽))
column.Width=column.ActualWidth;
//最后,将列设置为NaN。这将引发属性更改
//事件并重新计算宽度。
列宽=double.NaN;
}
基础。准备项目(项目);
}
}
我创建了一个函数,用于更新列表的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;
}
}
public void correctoredColumnWidths()
{
double remainingSpace=myList.ActualWidth;
如果(剩余空间>0)
{
对于(int i=0;i<(myList.View作为GridView.Columns.Count;i++)
如果(i!=2)
remainingSpace-=(myList.View作为GridView)。列[i]。实际宽度;
//为滚动条留出15像素的空闲空间
剩余空间-=15;
(myList.View作为GridView)。列[2]。宽度=剩余空间;
}
}
我喜欢user1333423的解决方案,只是它总是调整每一列的大小;我需要允许某些列的宽度固定。因此,在此版本中,宽度设置为“自动”的列将自动调整大小,而设置为固定数量的列将不会自动调整大小
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);
}
}
公共类AutoSizedGridView:GridView
{
HashSet\u自动宽度列;
受保护的覆盖无效准备项(ListViewItem)
{
if(_autoWidthColumns==null)
{
_autoWidthColumns=新HashSet();
foreach(列中的var列)
{
if(double.IsNaN(列宽))
_autoWidthColumns.Add(column.GetHashCode());
}
}
foreach(列中的GridViewColumn列)
{
if(_autoWidthColumns.Contains(column.GetHashCode()))
{
if(double.IsNaN(列宽))
column.Width=column.ActualWidth;
列宽=
<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>
<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>
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();
}
}
<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>
<Application.Resources>
<converters:GridViewColumHeaderWidthConverter x:Key="GridViewColumHeaderWidthConverter" />
</Application.Resources>
((INotifyCollectionChanged) MyListView.ItemsSource).CollectionChanged += CollectionChanged_Handler;
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;
}
}
}
private void MyListView_OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
CollectionChanged_Handler(sender, null);
}