Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding datagrid column width

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?

like image 825
manton Avatar asked Feb 16 '12 15:02

manton


2 Answers

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}
like image 91
H.B. Avatar answered Sep 29 '22 06:09

H.B.


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

like image 24
pedrito Avatar answered Sep 29 '22 06:09

pedrito