由DataGridTextColumn不能获取到父级DataContext引发的思考

  在项目中使用DataGrid需要根据业务动态隐藏某些列,思路都是给DataGrid中列的Visibility属性绑定值来实现(项目使用MVVM),如下

<DataGridTextColumn Header="Name" Binding="{Binding Name}" Visibility="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGrid}},Path=DataContext.IsVisible,Converter={StaticResource BooleanToVisibilityConverter}}"></DataGridTextColumn>


如果不是在DataGridTextColumn上绑定,那么这段代码是可以工作的,问题出在DataGridTextColumn上,我们来看它的继承层次

它不是FrameworkElement的派生类,所以它不具有DataContext属性,也就是说,即使DataGrid有DataContext,DataGridTextColumn也不能得到它,Visibility找不到DataContext自然绑定不上,这就是为什么上面的绑定失效的原因,同样其他类型的列也有同样的问题。那么如何优雅地解决问题呢?国际友人给出了这样一个方法,既然DataGridTextColumn不能从父级那里得到DataContext,那么直接给她的Visibility指定一个DataContext,实现如下

  • 首先创建一个可以承载DataContext的绑定代理类BindingProxy
  • 然后将这个BindingProxy当作资源,获得DataContext
  • 将DataGridTextColumn的Visibility的DataContext指定为这个BindingProxy

BindingProxy.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

namespace WPF_DataContext_Sample
{
    public class BindingProxy:Freezable
    {
        protected override Freezable CreateInstanceCore()
        {
            return new BindingProxy();
            
        }

        public object DataContext
        {
            get
            {
                return (object)GetValue(DataContextProperty);
            }
            set
            {
                SetValue(DataContextProperty, value);
            }
        }

        // Using a DependencyProperty as the backing store for DataContext.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataContextProperty =
            DependencyProperty.Register("DataContext", typeof(object), typeof(BindingProxy), new PropertyMetadata(null));
    }
}

MainWindow.xaml

<Window x:Class="WPF_DataContext_Sample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfDataContextSample="clr-namespace:WPF_DataContext_Sample"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <wpfDataContextSample:Converter x:Key="Converter"></wpfDataContextSample:Converter>
        
        <wpfDataContextSample:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"></wpfDataContextSample:BindingProxy>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="0.1*"/>
        </Grid.RowDefinitions>
        <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Students}">
            <DataGrid.Columns>

                <DataGridTextColumn Header="Id" Binding="{Binding Id}"></DataGridTextColumn>

                <!--这样的绑定会失败-->
                <!--<DataGridTextColumn Header="Name" Binding="{Binding Name}" Visibility="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DataGrid}},Path=DataContext.IsShow,Converter={StaticResource BooleanToVisibilityConverter}}"></DataGridTextColumn>-->

                <DataGridTextColumn Header="Name" Binding="{Binding Name}" Visibility="{Binding DataContext.IsShow,Source={StaticResource BindingProxy},Converter={StaticResource Converter}}"></DataGridTextColumn>
                
                <DataGridTextColumn Header="Sex" Binding="{Binding Sex}"></DataGridTextColumn>

            </DataGrid.Columns>
        </DataGrid>
        
        <StackPanel Orientation="Horizontal" Grid.Row="1">
            <Button Width="100" Height="30" Content="隐藏Name" Click="ButtonBase_OnClick"></Button>
        </StackPanel>
    </Grid>
</Window>

 

这样就能优雅地解决了这个问题

原文地址http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

Demo:WPF_DataContextAndDataGridTextColumn_Sample.rar

转载于:https://www.cnblogs.com/action98/p/3535934.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值