<DataGridTextColumn Binding="{Binding Name}" Width="*"/>
<DataGridTextColumn Binding="{Binding Change}" Width="Auto"/>
当Change
的值更新时,其列不会更新以适合新值。因此列保持太小并且值被剪裁
有什么想法吗?
答案 0 :(得分:55)
DataGrid会增加列大小以适应数据变长,但是当数据长度减少时,它不会自动减小列大小。在您的示例中,您正确对齐“更改”列,并使用“名称”列的其余空格。
现在,当“更改”属性变得足够大以至于应该增加列的宽度时,“名称”列会拒绝缩小以适应,因此您必须自己强制刷新。
1)在DataGridTextColumn Bindings中(除了* size列之外)设置NotifyTargetUpdated = True。
2)在DataGrid上,为TargetUpdated事件添加处理程序
3)在TargetUpdated事件处理程序中:
- a)将DataGrid的* size列的宽度设置为0
- b)在DataGrid上调用UpdateLayout()方法
- c)将DataGrid的* size列的宽度设置回新的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
}
}
答案 1 :(得分:2)
我的listview遇到了类似的问题,我在这里找到了how-to-autosize-and-right-align-gridviewcolumn-data-in-wpf在stackoverflow上的解决方案。
在我的情况下,它将这段代码添加到列表视图绑定到的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;
}
}
它适用于我,虽然有时用户会注意到列上的“闪烁”。
答案 2 :(得分:1)
WPF只会根据需要调整数据网格的列宽设置为自动,即:内容无法完全显示。因此,当内容的宽度缩小时,列不会调整大小,因为仍然可以完全看到内容。
我可以看到迫使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()
或两个(更新后,设置回自动)
答案 3 :(得分:0)
解决此问题的一种方法是在样式设置中定义列的width属性,并将该设置绑定到要绑定的对象的属性。
<DataGridTextColumn Binding="{Binding Change}" ElementStyle="{StaticResource ChangeColumnStyle}"/>
在您的ResourceDictionary中:
<Style TargetType="{x:Type DataGridTextColumn }" x:Key="ChangeColumnStyle">
<Setter Property="Width" Value="{Binding ColumnWidth}"
</Style>
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");
}
}
}
答案 4 :(得分:-1)
你试过这个吗?
<DataGridTextColumn Binding="{Binding Path= Id}" Header="ID" IsReadOnly="True" Width="1*" />