绑定数据网格列宽度

13

我有两个数据网格,每个网格只有一列。

<DataGrid.Columns>
   <DataGridTextColumn x:Name="FilterTextCol01" 
                       IsReadOnly="False" 
                       Width="{Binding ElementName=TextCol01, Path=ActualWidth, Mode=TwoWay}" />
</DataGrid.Columns>

其次:

<DataGridTextColumn CellStyle="{StaticResource DataGridColumnContentLeft}"
                    local:DataGridUtil.Name="TextCol01"
                    x:Name="TextCol01"
                    Header="TextCol01"
                    SortMemberPath="TextCol01"
                    Binding="{Binding TextCol01}" 
                    Width="Auto" 
                    IsReadOnly="True"/>

将第一列的宽度绑定到第二列的宽度不起作用。 如果我在代码中这样做:

FilterTextCol01.Width = TextCol01.ActualWidth;

它可以工作。 有人可以告诉我为什么第一种方法不起作用吗?

3个回答

22

由于 DataGrid 列是抽象对象,不会出现在窗口的逻辑树或可视树中。因此,您无法使用 ElementName 绑定它们的属性(这些绑定需要名称范围)。

您可以尝试使用 Sourcex:Reference,例如:

{Binding Source={x:Reference TextCol01}, Path=ActualWidth}

1
只读属性ActualWidth可以有双向绑定吗? - Clemens
3
@manton:不确定,取决于你何时遇到它们。WPF 中有许多细节,可能早晚某个时候会遇到,有时甚至可能在一两年后才会出现。 - H.B.
1
@manton:你正在使用设计师吧?我建议你忽略这个错误,因为它是由设计师创建的据我所知 - H.B.
1
@H.B. 谢谢!你无法想象这有多令人沮丧。我以前从未见过x:Reference! - Clint
@H.B. 你知道这个回答中的 <Binding ... /> 语法用于 MultiBinding 吗?我可以在我的问题中使用它:将DataGrid列宽绑定到另一个DataGrid的两列 - Steven
显示剩余4条评论

2

正如H.B.所说,该属性不在逻辑树或可视树中。

另外,请查看基于绑定代理的方法。

源代码

<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;
}

还可以参考https://stackoverflow.com/a/46787502/5381620


0

我一直在寻找类似的东西。 我已经找到了一个解决方案,因此我现在发布它,以帮助其他遇到相同问题的人。

在我的实现中,我为DataGridTextColumn的Header使用了自定义DataTemplate!

因此,将Width =“ {Binding ActualWidth,RelativeSource = {RelativeSource Mode = TemplatedParent}}”分配给用作DataGridColumnHeader的 TextBlock ,我可以将其 Width 设置为 DataGridTextColumn ActualWidth


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接