DataGrid列宽不会自动更新

  

Change的值更新时,其列不会更新以适合新值。 因此列保持太小并且值被剪裁。
有任何想法吗?

DataGrid将增加列大小以适应数据变长,但当数据长度减少时,它不会自动减小列大小。 在您的示例中,您正确对齐“更改”列,并使用“名称”列的其余空间。

现在,当“更改”属性变得足够大以至于应该增加列的宽度时,“名称”列拒绝缩小以适应,因此您必须自己强制刷新。

以下步骤应该为您完成此操作(我已经包含了一个示例应用程序来演示):

1)在DataGridTextColumn绑定(除了* size列之外的所有绑定)中设置NotifyTargetUpdated = True。
2)在DataGrid上,向TargetUpdated事件添加处理程序。
3)在TargetUpdated事件处理程序中:
– a)将DataGrid的* size列的宽度设置为0。
– b)在DataGrid上调用UpdateLayout()方法。
– c)将DataGrid的* size列的宽度设置回新的DataGridLength(1,DataGridLengthUnitType.Star)

示例XAML:

                 

示例代码背后:

 using System; using System.Collections.ObjectModel; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.ComponentModel; namespace DataGridTest { ///  /// Interaction logic for MainWindow.xaml ///  public partial class MainWindow : Window { private ObservableCollection myObjectList = new ObservableCollection(); 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 } } 

我的listview遇到了类似的问题,我在stackoverflow上的how-to-autosize-and-align-align-gridviewcolumn-data-in-wpf中找到了解决方案。

在我的例子中,它将这段代码添加到列表视图绑定到的observable集合的collectionchanged事件处理程序中:

 void 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将仅调整数据网格的列宽设置为自动,即:内容无法完全显示。 因此,当内容的宽度缩小时,列不会resize,因为仍然可以完全看到内容。

我可以看到迫使wpf重新计算列的宽度的唯一方法是将它们全部强制为0,然后在后面的代码中返回auto,抛出一个或两个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()或两个在那里(更新后和设置回自动)

解决此问题的一种方法是在样式设置中定义列的width属性,并将该设置绑定到要绑定的对象的属性。

  

在您的ResourceDictionary中:

  

ColumnWidth应该是对象的属性。 现在,如果您从“更改”属性的设置器更新此属性(通过使用一些自定义算法,将字体等内容记入帐户),并调用:

 RaisePropertyChanged("ColumnWidth"); 

它应该更新您的列宽。

  public int Change { get { return m_change; } set { if (m_change != value) { m_change = value; ColumnWidth = WidthAlgo(numberOfCharacters); RaisePropertyChanged("Change"); RaisePropertyChanged("ColumnWidth"); } } } 

你试过这个吗?