在项目中使用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

由DataGridTextColumn不能获取到父级DataContext引发的思考的更多相关文章

  1. Java IO,io,文件操作,删除文件,删除文件夹,获取文件父级目录

    Java IO,io,文件操作,删除文件,删除文件夹,获取文件父级目录 这里先简单的贴下常用的方法: File.separator //当前系统文件分隔符 File.pathSeparator // ...

  2. jQuery获取所有父级元素及同级元素及子元素的方法

    jQuery获取所有父级元素及同级元素及子元素的方法 1.获取父级元素 $("#id").parent() 获取其父级元素 $("#id").parents() ...

  3. mysql获取子父级节点

    获取所有子节点 DROP FUNCTION IF EXISTS `F_Co29_GetAllChildrenIdsOfTaskevent`;DELIMITER //CREATE FUNCTION `F ...

  4. SQL根据指定节点ID获取所有父级节点和子级节点

    --根据指定节点ID获取所有子节点-- WITH TEMP AS ( SELECT * FROM table_name WHERE Id=' --表的主键ID UNION ALL SELECT T0. ...

  5. SQL根据指定节点ID获取所有父级节点和子级节点(转载)

    --根据指定节点ID获取所有子节点-- WITH TEMP AS ( ' --表的主键ID UNION ALL SELECT T0.* FROM TEMP,table_name T0 WHERE TE ...

  6. el-tree点击获取直接父级的属性

    这里是可以一直往上获取它的直接父级的所有属性以及状态 通过这两个事件其中的一个 在方法里可以写上 methods:{ curCheck(data,state){ const curNode = thi ...

  7. mysql oracle sql获取树 父级 子级 及自己

    select * from ( select t.*,d.TABLE_NAME,d.QUERY_SQL,d.data_control_col,d.id table_id,d.where_sql fro ...

  8. jQuery使用(四):DOM操作之查找兄弟元素和父级元素

    查找兄弟元素 向下查找兄弟元素 next() nextAll() nextUntil() 向上查找兄弟元素 prev() prevAll() prevUntil() 查找所有兄弟元素 siblings ...

  9. js动态绑定class(当前父级div下的子元素有没有这个class,有的话移除,没有的话添加)

    <div class="layui-inline" id=‘’   onclick="changeType(id)">                ...

随机推荐

  1. 分享一个Fluent风格的邮件发送封装类

    C#中用SmtpClient发邮件很简单,闲着无事,简单封装一下 IEmailFactory public interface IEmailFactory { IEmailFactory SetHos ...

  2. 分布式服务框架 Zookeeper(转)

    分布式服务框架 Zookeeper -- 管理分布式环境中的数据 Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题 ...

  3. POJ 1066 Treasure Hunt --几何,线段相交

    题意: 正方形的房子,给一些墙,墙在区域内是封闭的,给你人的坐标,每穿过一道墙需要一把钥匙,问走出正方形需要多少把钥匙. 解法: 因为墙是封闭的,所以绕路也不会减少通过的墙的个数,还不如不绕路走直线, ...

  4. UVALive 6264 Conservation --拓扑排序

    题意:一个展览有n个步骤,告诉你每一步在那个场馆举行,总共2个场馆,跨越场馆需要1单位时间,先给你一些约束关系,比如步骤a要在b前执行,问最少的转移时间是多少. 解法:根据这些约束关系可以建立有向边, ...

  5. Android优化——UI检视利器:Hierarchy Viewer

    在Android的SDK工具包中,有很多十分有用的工具,可以帮助程序员开发和测试Android应用程序,大大提高其工作效率.其中的一款叫 Hierachy Viewer的可视化调试工具,可以很方便地在 ...

  6. intellij IDEA15 设置背景颜色

    File--> Settings 2. Appearance & Behavior --> Appearance 设置边框背景颜色 3. Editor --> Colors ...

  7. 基于PXC的MySQL高可用环境简单部署

    PXC简介 Percona XtraDB Cluster(简称PXC集群)提供了MySQL高可用的一种实现方法. 1.集群是有节点组成的,推荐配置至少3个节点,但是也可以运行在2个节点上. 2.每个节 ...

  8. 1140 Jam的计数法

    1140 Jam的计数法 2006年NOIP全国联赛普及组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Descri ...

  9. BPM到底能做什么?K2为你解读

    和平镇,镇如其名,几百年来一直很和平,夜不闭户路不拾遗.可是这一年来,镇上金光寺的和尚却开始不断离奇死亡…… 衙门里新调来的李捕头正好负责这个案子,经过了几个月的不眠不休,现场侦查和缜密推理之后,一切 ...

  10. poj3984迷宫问题 广搜+最短路径+模拟队列

    转自:http://blog.csdn.net/no_retreats/article/details/8146585   定义一个二维数组: int maze[5][5] = { 0, 1, 0, ...