由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>
这样就能优雅地解决了这个问题
Demo:WPF_DataContextAndDataGridTextColumn_Sample.rar
由DataGridTextColumn不能获取到父级DataContext引发的思考的更多相关文章
- Java IO,io,文件操作,删除文件,删除文件夹,获取文件父级目录
Java IO,io,文件操作,删除文件,删除文件夹,获取文件父级目录 这里先简单的贴下常用的方法: File.separator //当前系统文件分隔符 File.pathSeparator // ...
- jQuery获取所有父级元素及同级元素及子元素的方法
jQuery获取所有父级元素及同级元素及子元素的方法 1.获取父级元素 $("#id").parent() 获取其父级元素 $("#id").parents() ...
- mysql获取子父级节点
获取所有子节点 DROP FUNCTION IF EXISTS `F_Co29_GetAllChildrenIdsOfTaskevent`;DELIMITER //CREATE FUNCTION `F ...
- SQL根据指定节点ID获取所有父级节点和子级节点
--根据指定节点ID获取所有子节点-- WITH TEMP AS ( SELECT * FROM table_name WHERE Id=' --表的主键ID UNION ALL SELECT T0. ...
- SQL根据指定节点ID获取所有父级节点和子级节点(转载)
--根据指定节点ID获取所有子节点-- WITH TEMP AS ( ' --表的主键ID UNION ALL SELECT T0.* FROM TEMP,table_name T0 WHERE TE ...
- el-tree点击获取直接父级的属性
这里是可以一直往上获取它的直接父级的所有属性以及状态 通过这两个事件其中的一个 在方法里可以写上 methods:{ curCheck(data,state){ const curNode = thi ...
- 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 ...
- jQuery使用(四):DOM操作之查找兄弟元素和父级元素
查找兄弟元素 向下查找兄弟元素 next() nextAll() nextUntil() 向上查找兄弟元素 prev() prevAll() prevUntil() 查找所有兄弟元素 siblings ...
- js动态绑定class(当前父级div下的子元素有没有这个class,有的话移除,没有的话添加)
<div class="layui-inline" id=‘’ onclick="changeType(id)"> ...
随机推荐
- A python tool to static sim.log duration time
When working ALU IMS Patch team, we need to static the SU duration to add it to the patch report, th ...
- [转]excel set drop-down values based on vlookup
本文转自:http://stackoverflow.com/questions/10657811/set-drop-down-values-based-on-vlookup 问: I have a w ...
- NYOJ--1237最大岛屿
最大岛屿 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等.加勒比海盗,你知道吧?杰克船长驾驶着自己的的 ...
- Mysql如何清空数据库的所有表数据
1.先查询出库中的所有表,“db”是数据库名称 SELECT CONCAT('truncate table ',TABLE_NAME,';') AS a FROM INFORMATION_SCHEMA ...
- OpenSSH后门获取root密码及防范
OpenSSH后门获取root密码及防范 相对于Windows操作系统,Linux操作系统的密码较难获取.而很多Linux服务器都配置了Openssh服务,在获取root权限的情况下,可以通过修改或者 ...
- mac os利用xampp实现apache下的cgi
折腾了两天终于把问题解决了,mac os是10.10.3..够新了吧 系统原生的apache配置cgi老是配不好,突然发现xampp也有macos版的,准备下下来试试. 安装完成后,打开apache服 ...
- Lambda 表达式(C# 编程指南)
Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数. 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数.Lambda 表达式对于编写 LINQ 查 ...
- ES6严格模式use strict下的保留字
implements interface let package private protected public static yield
- 利用exif.js解决ios手机上传竖拍照片旋转90度问题
html5+canvas进行移动端手机照片上传时,发现ios手机上传竖拍照片会逆时针旋转90度,横拍照片无此问题:Android手机没这个问题. 因此解决这个问题的思路是:获取到照片拍摄的方向角,对非 ...
- C语言 日常小结
1.当数组当作函数参数的时候会退化为指针 #include<stdio.h> #include<stdlib.h> void sort(int a[]){ int num = ...