Ответ 1
DataGrid увеличит размеры столбцов, чтобы они соответствовали по мере того, как данные становятся длиннее, но не уменьшают размер столбцов при уменьшении длины данных. В вашем примере вы правильно выравниваете столбец "Изменить" и используете остальную часть пространства для столбца "Имя".
Теперь, когда свойство "Изменить" становится настолько большим, что оно должно увеличить ширину столбца, столбец "Имя" отказывается сжиматься для размещения, поэтому вам нужно принудительно обновить себя.
Следующие шаги должны сделать это для вас (я включил пример приложения в демонстрационную версию):
1) В ваших привязках DataGridTextColumn (все, кроме столбца размера *) установите NotifyTargetUpdated = True.
2) В DataGrid добавьте обработчик события TargetUpdated.
3) В обработчике событий TargetUpdated:
- a) Установите ширину столбца размера DataGrid * равным 0.
- b) Вызвать метод UpdateLayout() в DataGrid.
- c) Установите ширину столбца размера DataGrid * для новой DataGridLength (1, DataGridLengthUnitType.Star)
Пример XAML:
<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
}
}