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类

 BindingProxy

XAML引用BindingProxy

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

Visibility绑定

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

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

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MVVM是一种软件架构模式,用于将用户界面的逻辑与数据分离,以便更好地管理和维护代码。在WPF中,可以使用MVVM模式来实现DataGrid的动态列和编辑器。 首先,我们可以创建一个ViewModel类,该类将持有DataGrid的数据和列信息。我们可以使用ObservableCollection<T>来存储数据,这样当数据发生变化时,DataGrid会自动更新。 然后,我们可以在ViewModel中定义一个命令,用于处理用户对DataGrid中的数据进行编辑的操作。当用户点击编辑按钮时,命令会被调用,并传递要编辑的数据作为参数。 接下来,我们可以在View中使用DataGrid来展示ViewModel中的数据。通过绑定DataGrid的ItemsSource属性到ViewModel中的数据集合,可以实现动态列的效果。当ViewModel中的数据发生变化时,DataGrid会自动刷新。 在DataGrid的列定义中,我们可以使用DataGridTemplateColumn来定义自定义的编辑器。通过绑定该列的CellTemplate和CellEditingTemplate属性到ViewModel中的编辑器,在用户编辑数据时,可以使用自定义的编辑器来展示和保存数据。 最后,我们需要将View与ViewModel进行绑定,以实现数据的双向同步。可以使用DataBinding来将ViewModel中的属性与View中的控件进行绑定,这样当属性发生变化时,控件会自动更新,并且当用户对控件进行操作时,属性也会相应地更新。 总而言之,使用MVVM模式可以将DataGrid的动态列和编辑器实现得更加灵活和可维护。通过将数据和逻辑分离,我们可以更好地组织代码,并实现更好的用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值