且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

WPF 中 DataGridColumn 的绑定可见性

更新时间:2023-10-08 17:23:10

首先,DataGridTextColumn(或任何其他支持的 dataGrid 列)不位于 数据网格代码>.因此,默认情况下它不继承DataGridDataContext.但是,它仅适用于 Binding DP,不适用于 DataGridColumn 上的其他 DP.

First of all, DataGridTextColumn (or any other supported dataGrid column) does not lie in the Visual tree of the DataGrid. Hence, by default it doesn't inherit the DataContext of the DataGrid. However, it works for Binding DP only and for no other DP's on DataGridColumn.

由于它们不在同一个 VisualTree 中,任何使用 RelativeSource 获取 DataContext 的尝试都不会奏效,因为 DataGridTextColumn 无法遍历到 DataGrid.

Since they don't lie in the same VisualTree, any attempt to get the DataContext using RelativeSource won't work as well because DataGridTextColumn is unable to traverse up to the DataGrid.

不过,还有另外两种方法可以实现这一点:

There are two other ways to achieve this though:

首先使用 Freezable 类.Freezable 对象可以继承 DataContext,即使它们不在可视化或逻辑树中——我们可以利用这一点.

First using a Freezable class. Freezable objects can inherit the DataContext even when they’re not in the visual or logical tree –We can take advantage of that.

首先,创建一个继承自 FreezableData DP 的类,我们可以使用它在 XAML 中进行绑定:

First, create a class inheriting from Freezable and Data DP which we can use to bind in XAML:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object),
                                     typeof(BindingProxy));
}

现在,在 DataGrid 资源中添加它的一个实例,以便它可以继承 DataGrid 的 DataContext 并可以与其数据 DP 绑定:

Now, add an instance of it in DataGrid resources so that it can inherit the DataGrid's DataContext and can bind with its Data DP:

    <DataGrid>
        <DataGrid.Resources>
            <local:BindingProxy x:Key="proxy" Data="{Binding}"/>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn Visibility="{Binding Data.MyColumnVisibility,
                                                Source={StaticResource proxy}}"/>
        </DataGrid.Columns>
    </DataGrid>


第二,您可以使用 ElementNamex:Reference 引用 XAML 中的任何 UI 元素.但是,ElementName 仅适用于同一个可视化树,而 x:Reference 没有这样的约束.


Second, you can refer to any UI element in XAML using ElementName or x:Reference. However, ElementName works only in the same visual tree, whereas x:Reference doesn't have such constraints.

因此,我们也可以利用它来发挥我们的优势.在 XAML 中创建一个虚拟的 FrameworkElement,并将可见性设置为 collapsed.FrameworkElement 将从其父容器(可以是 Window 或 UserControl)继承 DataContext.

So, we can use that as well to our advantage. Create a dummy FrameworkElement in XAML with Visibility set to collapsed. The FrameworkElement will inherit the DataContext from its parent container, which can be a Window or UserControl.

并且可以在 DataGrid 中使用它:

And can use that in DataGrid:

    <FrameworkElement x:Name="dummyElement" Visibility="Collapsed"/>
    <DataGrid>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Test"
                                Binding="{Binding Name}"
                                Visibility="{Binding DataContext.IsEnable,
                                          Source={x:Reference dummyElement}}"/>
        </DataGrid.Columns>
    </DataGrid>