Reputation: 561
I have two datagrids with one column each. First:
<DataGrid.Columns>
<DataGridTextColumn x:Name="FilterTextCol01"
IsReadOnly="False"
Width="{Binding ElementName=TextCol01, Path=ActualWidth, Mode=TwoWay}" />
</DataGrid.Columns>
Second:
<DataGridTextColumn CellStyle="{StaticResource DataGridColumnContentLeft}"
local:DataGridUtil.Name="TextCol01"
x:Name="TextCol01"
Header="TextCol01"
SortMemberPath="TextCol01"
Binding="{Binding TextCol01}"
Width="Auto"
IsReadOnly="True"/>
Binding of the width of first column to the width of the second doesn't work. If I'm doing it in code that way:
FilterTextCol01.Width = TextCol01.ActualWidth;
It works. Could anyone tell me why the first approach doesn't work?
Upvotes: 13
Views: 14214
Reputation: 87
As H.B. said this property isn't in logical or visual tree.
Also have a look at this approach based on a binding proxy.
SourceCode
<DataGrid ItemsSource="{Binding Lines}" AutoGenerateColumns="False" >
<DataGrid.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="ProductId1" Binding="{Binding Path=Result[0]}" Width="{Binding Data.Columns[0].Width, Source={StaticResource proxy}, Mode=TwoWay}" />
<DataGridTextColumn Header="ProductId2" Binding="{Binding Path=Result[1]}" Width="{Binding Data.Columns[1].Width, Source={StaticResource proxy}, Mode=TwoWay}"/>
</DataGrid.Columns>
</DataGrid>
class BindingProxy : Freezable
{
//Override of Freezable
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
public class Column : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected internal void OnPropertyChanged(string propertyname)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
public DataGridLength Width
{
get { return m_width; }
set { m_width = value; OnPropertyChanged("Width"); }
}
DataGridLength m_width;
}
Also see https://stackoverflow.com/a/46787502/5381620
Upvotes: 2
Reputation: 892
I've been searching for something like this. I found a solution so i'm posting it in order to help some other person with the same issue.
In my implementation i use a Custom DataTemplate for the Header of the DataGridTextColumn!!
So assigning Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=TemplatedParent}}"
to the TextBlock
used as DataGridColumnHeader i am able to set its Width
to the DataGridTextColumn
ActualWidth
Upvotes: 0
Reputation: 185300
Because DataGrid
columns are abstract objects which do not appear in the logical or visual tree of your window. You cannot bind properties on them using ElementName
(there will be no namescope which is needed for those bindings).
You can try using Source
and x:Reference
instead, e.g.
{Binding Source={x:Reference TextCol01}, Path=ActualWidth}
Upvotes: 22