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>
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; }); } } } }
显示效果如下
本该隐藏的第三列,没有隐藏,比较困惑,然后百度了一下,在两个网站上得到了答案,网站一,网站二
出现问题的原因是,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); } } }
XAML引用BindingProxy
<local:BindingProxy x:Key="proxy" Data="{Binding}"/>
Visibility绑定
<DataGridTextColumn Header="列三" Visibility="{Binding Data.IsVisibility,Source={StaticResource proxy}}"/>
效果如下,列二用的是方法一,列三用的是方法二
作为新手,只能理解如此,希望有大神可以给好好的讲解一下,谢谢。
作者:眾尋
出处:https://www.cnblogs.com/ZXdeveloper/p/4682736.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本