最近的一个项目,需要在部分用户登录的时候,隐藏DataGrid中的一列,但是常规的绑定不好使,在下面举个例子。

XAML部分代码

  1. <Window x:Class="DataGridColumn.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:local="clr-namespace:DataGridColumn"
  5. Title="MainWindow" Height="350" Width="525">
  6. <Grid>
  7. <Grid.RowDefinitions>
  8. <RowDefinition Height="50"/>
  9. <RowDefinition Height="*"/>
  10. </Grid.RowDefinitions>
  11. <StackPanel Grid.Row="0">
  12. <Button Content="显示" Command="{Binding Button1Command}"/>
  13. <Button Content="隐藏" Command="{Binding Button2Command}"/>
  14. </StackPanel>
  15. <DataGrid Grid.Row="1" AutoGenerateColumns="False">
  16. <DataGrid.Columns>
  17. <DataGridTextColumn Header="列一"/>
  18. <DataGridTextColumn Header="列二"/>
  19. <DataGridTextColumn Header="列三" Visibility="{Binding DataContext.IsVisibility,RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
  20. </DataGrid.Columns>
  21. </DataGrid>
  22. </Grid>
  23. </Window>

XAML

ViewModel部分代码

  1. using GalaSoft.MvvmLight.Command;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows;
  9.  
  10. namespace DataGridColumn
  11. {
  12. public class MainWindowVM : INotifyPropertyChanged
  13. {
  14. public MainWindowVM()
  15. {
  16. IsVisibility = Visibility.Hidden;
  17. }
  18. public event PropertyChangedEventHandler PropertyChanged;
  19. private void INotifyPropertyChanged(string name)
  20. {
  21. if (PropertyChanged != null)
  22. {
  23. PropertyChanged(this, new PropertyChangedEventArgs(name));
  24. }
  25. }
  26.  
  27. private Visibility isVisibility;
  28.  
  29. public Visibility IsVisibility
  30. {
  31. get { return isVisibility; }
  32. set
  33. {
  34. isVisibility = value;
  35. INotifyPropertyChanged("IsVisibility");
  36. }
  37. }
  38.  
  39. private RelayCommand button1Command;
  40.  
  41. public RelayCommand Button1Command
  42. {
  43. get
  44. {
  45. return button1Command = new RelayCommand(
  46. () =>
  47. {
  48. IsVisibility = Visibility.Visible;
  49. });
  50. }
  51. }
  52.  
  53. private RelayCommand button2Command;
  54.  
  55. public RelayCommand Button2Command
  56. {
  57. get
  58. {
  59. return button2Command = new RelayCommand(
  60. () =>
  61. {
  62. IsVisibility = Visibility.Hidden;
  63. });
  64. }
  65. }
  66. }
  67. }

ViewModel

显示效果如下

本该隐藏的第三列,没有隐藏,比较困惑,然后百度了一下,在两个网站上得到了答案,网站一网站二

出现问题的原因是,DataGridTextColumn不属于Visual Tree

解决方案有两种:

一、采用代理(网站一)

1、添加一个FrameworkElement的代理

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

2、用一个不可见的ContentControl绑定上一步的FrameworkElement代理

  1. <ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"/>

3、用代理做为Visibility的数据源

  1. <DataGridTextColumn Header="列二" Visibility="{Binding DataContext.IsVisibility,Source={StaticResource ProxyElement}}"/>

二、使用Freezable(网站二)

根据MSDN里Freezable的相关文档,在Remarks下有这样的一句话

  • Detailed change notification: Unlike other DependencyObject objects, a Freezable object provides change notifications when sub-property values change.

大意就是和其他的DependencyObject相比,在子属性值更改时, Freezable 对象提供更改通知。个人认为应该是由于Freezable有这个特点,所以才能被用在这里。

代码如下

BindingProxy类

  1. public class BindingProxy:Freezable
  2. {
  3. protected override Freezable CreateInstanceCore()
  4. {
  5. return new BindingProxy();
  6. //throw new NotImplementedException();
  7. }
  8.  
  9. public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
  10.  
  11. public object Data
  12. {
  13. get { return (object)GetValue(DataProperty); }
  14. set { SetValue(DataProperty, value); }
  15. }
  16. }

BindingProxy

XAML引用BindingProxy

  1. <local:BindingProxy x:Key="proxy" Data="{Binding}"/>

Visibility绑定

  1. <DataGridTextColumn Header="列三" Visibility="{Binding Data.IsVisibility,Source={StaticResource proxy}}"/>

效果如下,列二用的是方法一,列三用的是方法二

作为新手,只能理解如此,希望有大神可以给好好的讲解一下,谢谢。

MVVM框架下 WPF隐藏DataGrid一列的更多相关文章

  1. MVVM框架从WPF移植到UWP遇到的问题和解决方法

    MVVM框架从WPF移植到UWP遇到的问题和解决方法 0x00 起因 这几天开始学习UWP了,之前有WPF经验,所以总体感觉还可以,看了一些基础概念和主题,写了几个测试程序,突然想起来了前一段时间在W ...

  2. MVVM模式下WPF动态绑定展示图片

    MVVM模式下WPF动态展示图片,界面选择图标,复制到项目中固定目录下面,保存到数据库的是相对路径,再次读取的时候是根据数据库的相对路径去获取项目中绝对路径的图片展示. 首先在ViewModel中 / ...

  3. MVVM框架下,WPF实现Datagrid里的全选和选择

    最近的一个项目是用MVVM实现,在实现功能的时候,就会有一些东西,和以前有很大的区别,项目中就用到了常用的序号,就是在Datagrid里的一个字段,用checkbox来实现. 既然是MVVM,就要用到 ...

  4. 关于使用MVVM模式在WPF的DataGrid控件中实现ComboBox编辑列

    最近在做一个组态软件的项目,有一个需求需要在建立IO设备变量的时候选择变量的类型等. 建立IO变量的界面是一个DataGrid实现的,可以一行一行的新建变量,如下如所示: 这里需要使用带有ComboB ...

  5. WPF MVVM框架下,VM界面写控件

    MVVM正常就是在View页面写样式,ViewModel页面写逻辑,但是有的时候纯在View页面写样式并不能满足需求.我最近的这个项目就遇到了,因此只能在VM页面去写样式控件,然后绑定到View页面. ...

  6. mybatis框架下解决数据库中表的列的字段名和实体类属性不相同的问题

    导包.... 实体类中的属性,getter,setter,tostring,构造等方法就不写了 private int id; private String orderNo; private floa ...

  7. mvvm框架下页面与ViewModel的各种参数传递方式

    传单个参数的话在xaml用     Command={Binding ViewModel的事件处理名称}    CommandParameter={Binding 要传递的控件名称} ViewMode ...

  8. wpf 获取datagrid 模板列中的控件

    目前采用的 方法  (网上提供的一款) public static DataGridRow GetRow(DataGrid datagrid, int columnIndex)        {    ...

  9. C# wpf中DataGrid 支持汇总行

    最近有一个需求,需要汇总金额,份额等字段.我们使用的是原生的WPF控件,自己开发了一套Template.而没有使用比较成熟的第三方控件.所以这个功能得自己开发.并且要做成控件层次的功能. 当然也可以这 ...

随机推荐

  1. ECF R9(632E) & DP

    Description: 给你$n$个数可以任取$k$个(可重复取),输出所有可能的和. $n \leq 1000,a_i \leq 1000$ Solution: 好神的DP,我们排序后把每个数都减 ...

  2. Android开发 SQLite数据库应用笔记(一)

    注意: 1.public Cursor rawQuery(String sql, String[] selectionArgs) Cursor游标是查询后返回的结果集合,游标的意思是指向集合中的某行. ...

  3. Linux Shell 截取字符串

    Linux Shell 截取字符串 shell中截取字符串的方法很多 ${var#*/} ${var##*/} ${var%/*} ${var%%/*} ${var:start:len} ${var: ...

  4. 在php中定义常量时,const与define的区别?

    问]在php中定义常量时,const与define的区别?  [答]使用const使得代码简单易读,const本身就是一个语言结构,而define是一个函数.另外const在编译时要比define快很 ...

  5. 前端自动化工具gulp自动添加版本号

    之前,我介绍了学习安装并配置前端自动化工具Gulp,觉得gulp确实比grunt的配置简单很多,于是我决定再深入学习一下gulp,就去网上查了资料,发现gulp还可以自动添加版本号,这个功能就为我平时 ...

  6. [ios]关于用FMDB 操作数据库 删除 tableView 后刷新

    刚了解使用fmdb,从数据库获取数据 绑定到一个可变数组classNameItems //从ClassList表取得数据 FMResultSet *classInfo=[db executeQuery ...

  7. java的英文词频算法

    java实现的英文词频算法,通常是采用单词树来实现的.使用java实现词频统计,为了统计词汇出现频率,最简单的做法是再建立一个map,其中,key是单词,value代表次数.将文章从头读到尾,读到一个 ...

  8. console对象-转

    console对象 来自<JavaScript 标准参考教程(alpha)>,by 阮一峰 目录 开发者工具 console对象 console.log() console.debug() ...

  9. C# 匿名对象随笔

      最新更新请访问: http://denghejun.github.io   C#中匿名对象的一般写法是这样的: object o=new {Name="TestName"}; ...

  10. Linux上传下载文件快捷命令

    远程链接Linux(如SecrueCRT),要上传文件很下载文件到Linux服务器,只需要使用sz或者rz命令即可快速下载和上传文件了. 使用方法: 1.首先确保Linux服务器系统中安装了lrzsz ...