MVVM框架下 WPF隐藏DataGrid一列
最近的一个项目,需要在部分用户登录的时候,隐藏DataGrid中的一列,但是常规的绑定不好使,在下面举个例子。
XAML部分代码
<Window x:Class="DataGridColumn.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataGridColumn"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Button Content="显示" Command="{Binding Button1Command}"/>
<Button Content="隐藏" Command="{Binding Button2Command}"/>
</StackPanel>
<DataGrid Grid.Row="1" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="列一"/>
<DataGridTextColumn Header="列二"/>
<DataGridTextColumn Header="列三" Visibility="{Binding DataContext.IsVisibility,RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
XAML
ViewModel部分代码
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows; namespace DataGridColumn
{
public class MainWindowVM : INotifyPropertyChanged
{
public MainWindowVM()
{
IsVisibility = Visibility.Hidden;
}
public event PropertyChangedEventHandler PropertyChanged;
private void INotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
} private Visibility isVisibility; public Visibility IsVisibility
{
get { return isVisibility; }
set
{
isVisibility = value;
INotifyPropertyChanged("IsVisibility");
}
} private RelayCommand button1Command; public RelayCommand Button1Command
{
get
{
return button1Command = new RelayCommand(
() =>
{
IsVisibility = Visibility.Visible;
});
}
} private RelayCommand button2Command; public RelayCommand Button2Command
{
get
{
return button2Command = new RelayCommand(
() =>
{
IsVisibility = Visibility.Hidden;
});
}
}
}
}
ViewModel
显示效果如下

本该隐藏的第三列,没有隐藏,比较困惑,然后百度了一下,在两个网站上得到了答案,网站一,网站二
出现问题的原因是,DataGridTextColumn不属于Visual Tree
解决方案有两种:
一、采用代理(网站一)
1、添加一个FrameworkElement的代理
<Window.Resources>
<FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>
</Window.Resources>
2、用一个不可见的ContentControl绑定上一步的FrameworkElement代理
<ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"/>
3、用代理做为Visibility的数据源
<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类
public class BindingProxy:Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
//throw new NotImplementedException();
} public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
}
BindingProxy
XAML引用BindingProxy
<local:BindingProxy x:Key="proxy" Data="{Binding}"/>
Visibility绑定
<DataGridTextColumn Header="列三" Visibility="{Binding Data.IsVisibility,Source={StaticResource proxy}}"/>
效果如下,列二用的是方法一,列三用的是方法二


作为新手,只能理解如此,希望有大神可以给好好的讲解一下,谢谢。
MVVM框架下 WPF隐藏DataGrid一列的更多相关文章
- MVVM框架从WPF移植到UWP遇到的问题和解决方法
MVVM框架从WPF移植到UWP遇到的问题和解决方法 0x00 起因 这几天开始学习UWP了,之前有WPF经验,所以总体感觉还可以,看了一些基础概念和主题,写了几个测试程序,突然想起来了前一段时间在W ...
- MVVM模式下WPF动态绑定展示图片
MVVM模式下WPF动态展示图片,界面选择图标,复制到项目中固定目录下面,保存到数据库的是相对路径,再次读取的时候是根据数据库的相对路径去获取项目中绝对路径的图片展示. 首先在ViewModel中 / ...
- MVVM框架下,WPF实现Datagrid里的全选和选择
最近的一个项目是用MVVM实现,在实现功能的时候,就会有一些东西,和以前有很大的区别,项目中就用到了常用的序号,就是在Datagrid里的一个字段,用checkbox来实现. 既然是MVVM,就要用到 ...
- 关于使用MVVM模式在WPF的DataGrid控件中实现ComboBox编辑列
最近在做一个组态软件的项目,有一个需求需要在建立IO设备变量的时候选择变量的类型等. 建立IO变量的界面是一个DataGrid实现的,可以一行一行的新建变量,如下如所示: 这里需要使用带有ComboB ...
- WPF MVVM框架下,VM界面写控件
MVVM正常就是在View页面写样式,ViewModel页面写逻辑,但是有的时候纯在View页面写样式并不能满足需求.我最近的这个项目就遇到了,因此只能在VM页面去写样式控件,然后绑定到View页面. ...
- mybatis框架下解决数据库中表的列的字段名和实体类属性不相同的问题
导包.... 实体类中的属性,getter,setter,tostring,构造等方法就不写了 private int id; private String orderNo; private floa ...
- mvvm框架下页面与ViewModel的各种参数传递方式
传单个参数的话在xaml用 Command={Binding ViewModel的事件处理名称} CommandParameter={Binding 要传递的控件名称} ViewMode ...
- wpf 获取datagrid 模板列中的控件
目前采用的 方法 (网上提供的一款) public static DataGridRow GetRow(DataGrid datagrid, int columnIndex) { ...
- C# wpf中DataGrid 支持汇总行
最近有一个需求,需要汇总金额,份额等字段.我们使用的是原生的WPF控件,自己开发了一套Template.而没有使用比较成熟的第三方控件.所以这个功能得自己开发.并且要做成控件层次的功能. 当然也可以这 ...
随机推荐
- PC端一些非经典兼容性问题小札
IE10默认在input框中输入内容后会显示一个‘X’按钮,方便删除输入的所有内容. 在password输入框显示一个眼睛的按钮,去掉叉叉和眼睛的方法如下: ::-ms-clear { display ...
- paramiko模块的安装
1.找到自己python安装的目录(默认路径:C:\Users\zhangliyuan\AppData\Local\Programs\Python\Python35) 注:cmd中所有命令 2.进入S ...
- C++ Primer Plus 第六版笔记
C++ Primer Plus 第六版笔记 关于对象声明的思考 转自:http://www.cnblogs.com/weiqubo/archive/2009/11/02/1930042.html C+ ...
- IDEA+Tomcat+JRebel热部署1
所需资源下载: jrebel_6.4.2a 概述 JRebel是一个J2EE热部署的工具.使用它可以减少浪费8-18%的开发时间在项目的构建和部署上.之前只是听说过,一直没有实践,今天实际使用了一把 ...
- ASP.NET Razor - html中使用if else
参考: http://www.runoob.com/aspnet/razor-cs-loops.html <select id="task_isfirst" class=&q ...
- 怎么统计指定文件夹下含有.xml格式的文件数目
如何统计指定文件夹下含有.xml格式的文件数目?如题 ------解决思路----------------------Directory.GetFiles(@"路径", " ...
- duplicate symbols for architecture arm64 after xCode 8.0 update
Xcode IDE 从7.3.1 update 到 8.0 之后出现的问题 一个错误把我困扰了两天之久,最终找到解决办法我欣喜若狂. 错误发生原因:Xcode IDE 从7.3.1 update ...
- zend studio8编辑器乱码问题解决办法
截图一张:
- 用Unity实现时间倒退效果
记得以前看过一个电影,叫做<独立游戏大电影>,其中有个一个游戏可以实现时间回退的功能,可以像倒带一样,十分有趣.因此我就想着用Unity也实现一个类似的简单Demo,说不定哪天会用到. 效 ...
- jquery 选择元素