<DataGridTextColumn Binding="{Binding Name}" Width="*"/>
<DataGridTextColumn Binding="{Binding Change}" Width="Auto"/>
Change
的值更新时,其列不会更新以适应新值。因此,该列保持太小并且该值被裁剪。
有任何想法吗?
DataGrid会在数据变长时增加列的大小,但是当数据长度减小时,它不会自动减小列的大小。在你的例子中,你将“Change”列右对齐,并使用其余的空间来放置“Name”列。
现在,当“Change”属性变得足够大以增加列的宽度时,“Name”列拒绝缩小以适应,因此您必须强制刷新。
1)在DataGridTextColumn绑定中(除了您*大小的列),设置NotifyTargetUpdated=True
2)在您的DataGrid上,添加一个TargetUpdated事件处理程序。
3)在您的TargetUpdated事件处理程序中:
-- a) 将DataGrid的*大小列的宽度设置为0。
-- b) 在DataGrid上调用UpdateLayout()方法。
-- c) 将DataGrid的*大小列的宽度重新设置为new DataGridLength(1, DataGridLengthUnitType.Star)
<Window x:Class="DataGridTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<CollectionViewSource x:Key="MyObjectCollection" />
</Window.Resources>
<DockPanel>
<Button DockPanel.Dock="Bottom" Content="Click to Make Item 1s Text Longer" Click="Button_Click" />
<Grid>
<DataGrid x:Name="dg" ItemsSource="{Binding Source={StaticResource MyObjectCollection}}" AutoGenerateColumns="False" TargetUpdated="dg_TargetUpdated">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding First}" Width="1*"/>
<DataGridTextColumn Binding="{Binding Last, NotifyOnTargetUpdated=True}" Width="Auto" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</DockPanel>
</Window>
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.ComponentModel;
namespace DataGridTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ObservableCollection<MyObject> myObjectList = new ObservableCollection<MyObject>();
public MainWindow()
{
InitializeComponent();
(this.FindResource("MyObjectCollection") as CollectionViewSource).Source = this.myObjectList;
this.myObjectList.Add(new MyObject() { First = "Bob", Last = "Jones" });
this.myObjectList.Add(new MyObject() { First = "Jane", Last = "Doe" });
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.myObjectList[0].Last = "BillyOBrian";
}
private void dg_TargetUpdated(object sender, DataTransferEventArgs e)
{
dg.Columns[0].Width = 0;
dg.UpdateLayout();
dg.Columns[0].Width = new DataGridLength(1, DataGridLengthUnitType.Star);
}
}
public class MyObject : INotifyPropertyChanged
{
private string firstName;
public string First
{
get { return this.firstName; }
set
{
if (this.firstName != value)
{
this.firstName = value;
NotifyPropertyChanged("First");
}
}
}
private string lastName;
public string Last
{
get { return this.lastName; }
set
{
if (this.lastName != value)
{
this.lastName = value;
NotifyPropertyChanged("Last");
}
}
}
public MyObject() { }
#region -- INotifyPropertyChanged Contract --
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion INotifyPropertyChanged Contract
}
}
dg.Columns[0].Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
。 - Gerardvoid listview_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
// this is a listview control
GridView view = this.View as GridView;
foreach(GridViewColumn c in view.Columns) {
if(double.IsNaN(c.Width)) {
c.Width = c.ActualWidth;
}
c.Width = double.NaN;
}
}
在我的环境中它是可用的,但有时用户可能会注意到列上的“闪烁”。
如果需要,WPF将仅调整设置为自动的数据网格列宽度大小,即:无法完全显示内容。因此,当内容的宽度缩小时,列不会重新调整大小,因为内容仍然可以完全看到。
我唯一能想到的强制WPF重新计算列宽度的方法是在代码后台中将它们全部强制设置为0,然后再设置为自动,并加入一两个updateLayout(),但这并不是很好的编程方式 :-/
基本上,在您的代码后台:
foreach (DataGridColumn c in dg.Columns)
c.Width = 0;
// Update your DG's source here
foreach (DataGridColumn c in dg.Columns)
c.Width = DataGridLength.Auto;
你可能需要在那里的某个地方加上一个或两个 dg.UpdateLayout()
(在更新和设置回自动之后)
<DataGridTextColumn Binding="{Binding Change}" ElementStyle="{StaticResource ChangeColumnStyle}"/>
<Style TargetType="{x:Type DataGridTextColumn }" x:Key="ChangeColumnStyle">
<Setter Property="Width" Value="{Binding ColumnWidth}"
</Style>
ColumnWidth 应该是您对象的一个属性。现在,如果您从“Change”属性的setter中更新此属性(使用一些自定义算法,考虑字体等因素),并调用:
RaisePropertyChanged("ColumnWidth");
它应该更新您的列宽度。
public int Change
{
get { return m_change; }
set
{
if (m_change != value)
{
m_change = value;
ColumnWidth = WidthAlgo(numberOfCharacters);
RaisePropertyChanged("Change");
RaisePropertyChanged("ColumnWidth");
}
}
}
你试过这个吗?
<DataGridTextColumn Binding="{Binding Path= Id}" Header="ID" IsReadOnly="True" Width="1*" />
Auto
以外的任何值,问题将消失,但是如果您需要它,则Scott在下面的答案是正确的方法! 我循环遍历了所有自动列“dataGrid.Columns.Where(c => c.Width.IsAuto)”并执行了Scott所做的操作。 - Shahin Dohan