WPF中DataGridColumn的绑定可见性

bt1cpqcv  于 2023-02-05  发布在  其他
关注(0)|答案(4)|浏览(273)

如何通过绑定隐藏WPF DataGrid中的列?
我是这么做的:

<DataGridTextColumn Header="Column header"
                    Binding="{Binding ColumnValue}"
                    Width="100"
                    ElementStyle="{StaticResource DataGridRightAlign}"
                    Visibility="{Binding MyColumnVisibility}" />

这是我得到的(除了列仍然可见):
系统窗口数据错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。绑定表达式:路径= MyColumnVisibility;数据项=空;目标元素为"数据网格文本列"(哈希代码= 1460142);目标属性为"可见性"(类型为"可见性")
如何固定装订?

jv4diomz

jv4diomz1#

首先,**DataGridTextColumn(或任何其他受支持的dataGrid列)不位于DataGrid**的Visual树中。因此,默认情况下,**它不继承DataGrid**的DataContext。但是,它仅适用于Binding DP,不适用于DataGridColumn上的其他DP。
因为它们不在同一个VisualTree中,所以任何使用RelativeSource获取DataContext的尝试都不会成功,因为DataGridTextColumn无法遍历到DataGrid
不过,还有另外两种方法可以实现这一点:

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

首先,创建一个继承自FreezableData DP的类,我们可以使用它在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并与其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没有这样的约束。

因此,我们也可以利用它。在XAML中创建一个虚拟的FrameworkElement,将Visibility设置为collapsed。FrameworkElement将从其父容器继承DataContext,该容器可以是Window或UserControl。
并且可以在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>
q3aa0525

q3aa05252#

<Window.Resources>
    <ResourceDictionary>
        <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}" />
    </ResourceDictionary>
</Window.Resources>

<!-- Necessary for binding to resolve: adds reference to ProxyElement to tree.-->
<ContentControl Content="{StaticResource ProxyElement}" Visibility="Collapsed" />
<mch:MCHDataGrid Height="350"
                  AutoGenerateColumns="False"
                  FlowDirection="LeftToRight"
                  ItemsSource="{Binding PayStructures}"
                  SelectedItem="{Binding SelectedItem}">
    <DataGrid.Columns>
         <DataGridTemplateColumn Width="70"
                                 Header="name"
                                 IsReadOnly="True"
                                 Visibility="{Binding DataContext.IsShowName,
                                 Source={StaticResource ProxyElement}}">
             <DataGridTemplateColumn.CellTemplate>
                 <DataTemplate>
                     <TextBlock Text="{Binding FieldName}" />
                 </DataTemplate>
             </DataGridTemplateColumn.CellTemplate>
         </DataGridTemplateColumn>                   
     </DataGrid.Columns>
</mch:MCHDataGrid>

视图模型中绑定属性示例:

private Visibility _isShowName;

public Visibility IsShowName
{
    get { return _isShowName; }
    set
    {
        _isShowName = value;
        OnPropertyChanged();
    }
}
p8h8hvxi

p8h8hvxi3#

我喜欢的另一个简单的解决方案是在与DataGrid相同的级别上添加一个虚拟的折叠FrameworkElement,然后可以使用FrameworkElement作为带有x:Reference标记扩展的BindingSource
比如这样一个例子:

<FrameworkElement x:Name="FrameWorkElementProxy" Visibility="Collapsed"/>
<DataGrid>
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="post" 
            Visibility="{Binding DataContext.DataGridColumnVisibility, Source={x:Reference Name=FrameWorkElementProxy}}"/>
    </DataGrid.Columns>
</DataGrid>
z9smfwbn

z9smfwbn4#

如果您在XAML中创建了Window/Page/UserControl DataContext对象,另一个快速选项如下所示:

<Window.DataContext>  
    <local:ViewModel x:Name="MyDataContext"/>  
</Window.DataContext>

您可以使用绑定Source中DataContext对象的x:Name添加x:Reference

<DataGridTextColumn Header="Column header"
                    Binding="{Binding ColumnValue}"
                    Width="100"
                    ElementStyle="{StaticResource DataGridRightAlign}"
                    Visibility="{Binding MyColumnVisibility, Source={x:Reference Name=MyDataContext}}"

这样,您就可以避免使用绑定DataContext.MyColumnVisibility,而只使用绑定MyColumnVisibility

相关问题