【问题标题】:Binding datagrid column width绑定数据网格列宽
【发布时间】:2012-03-07 23:41:36
【问题描述】:

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

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

它有效。 谁能告诉我为什么第一种方法不起作用?

【问题讨论】:

    标签: c# wpf xaml data-binding datagrid


    【解决方案1】:

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

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

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

    【讨论】:

    • 只读属性 ActualWidth 可以有双向绑定吗?
    • @H.B.伟大的。谢谢它的工作原理。我永远不会猜到。这么深埋的东西,需要多久才能知道?
    • @manton: 不知道,取决于你什么时候偶然发现它们,WPF 中有很多细节迟早会遇到,有时甚至在一年或几年之后我想.
    • @manton:我想你在使用设计师?我建议您忽略该错误,因为它是由设计师 as far as i know 创建的。
    • @H.B.谢谢!你无法想象这是多么令人沮丧。从字面上看,以前从未见过 x:Reference!
    【解决方案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

    【讨论】:

      【解决方案3】:

      我一直在寻找类似的东西。我找到了一个解决方案,所以我发布它是为了帮助其他有同样问题的人。

      在我的实现中,我使用自定义 DataTemplate 作为 DataGridTextColumn 的标题!!

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

      【讨论】:

        猜你喜欢
        • 2011-06-24
        • 1970-01-01
        • 2010-09-22
        • 2012-06-21
        • 1970-01-01
        • 2017-06-11
        • 1970-01-01
        • 1970-01-01
        • 2016-11-13
        相关资源
        最近更新 更多