【笔记】WPF中如何的动态设置DataGridTextColumn是否显示

要动态控制 DataGridTextColumn 是否显示,不能用普通触发器或直接绑定,因为列不在可视树中。做法是:

  • 给列挂"可绑定的可见性"附加属性;
  • 用绑定把该属性连到一个状态值(如 ViewModel 的 SelectedTabItemData.State 或当前选中行的 State);
  • 用转换器把状态转成 Visible/Collapsed。

示例:

xaml 复制代码
<UserControl x:Class="H.Sxb.Modules.Bill.View.OrderBillControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:H.Sxb.Modules.Bill.View"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             mc:Ignorable="d">
    <UserControl.Resources>
        <local:IntInSetToVisibilityConverter x:Key="IntInSetToVisibilityConverter" />
        <local:BindingProxy x:Key="dgProxy" Data="{Binding}" />
    </UserControl.Resources>

    <!-- ... -->

    <DataGrid x:Name="dg"
              ItemsSource="{Binding PageResponse.Items}">
        <DataGrid.Columns>
            <!-- 顶部表格:当 State 为 1/2/3 显示"实发金额",为 2/3 显示"收货金额" -->
            <DataGridTextColumn Binding="{Binding MinusAmount}"
                                Header="实发金额"
                                local:DataGridColumnExtensions.BindableVisibility="{Binding Data.SelectedTabItemData.State,
                                    Source={StaticResource dgProxy},
                                    Converter={StaticResource IntInSetToVisibilityConverter},
                                    ConverterParameter=1,2,3}" />
            <DataGridTextColumn Binding="{Binding ReceivableAmount}"
                                Header="收获金额"
                                local:DataGridColumnExtensions.BindableVisibility="{Binding Data.SelectedTabItemData.State,
                                    Source={StaticResource dgProxy},
                                    Converter={StaticResource IntInSetToVisibilityConverter},
                                    ConverterParameter=2,3}" />
            <!-- 其余列... -->
        </DataGrid.Columns>
    </DataGrid>
</UserControl>
  • IntInSetToVisibilityConverter
csharp 复制代码
using System;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Data;

namespace H.Sxb.Modules.Bill.View
{
    public class IntInSetToVisibilityConverter : IValueConverter
    {
        public bool Invert { get; set; }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var text = parameter?.ToString() ?? string.Empty;
            var set = text.Split(new[] { ' '}, StringSplitOptions.RemoveEmptyEntries)
                          .Select(s => s.Trim()).ToArray();
            var val = value?.ToString();
            var match = set.Any(s => string.Equals(s, val, StringComparison.OrdinalIgnoreCase));
            if (Invert) match = !match;
            return match ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
            Binding.DoNothing;
    }
}
  • DataGridColumnExtensions
csharp 复制代码
using System.Windows;
using System.Windows.Controls;

namespace H.Sxb.Modules.Bill.View
{
    public static class DataGridColumnExtensions
    {
        public static readonly DependencyProperty BindableVisibilityProperty =
            DependencyProperty.RegisterAttached(
                "BindableVisibility",
                typeof(Visibility),
                typeof(DataGridColumnExtensions),
                new PropertyMetadata(Visibility.Visible, OnBindableVisibilityChanged));

        public static void SetBindableVisibility(DependencyObject obj, Visibility value) =>
            obj.SetValue(BindableVisibilityProperty, value);

        public static Visibility GetBindableVisibility(DependencyObject obj) =>
            (Visibility)obj.GetValue(BindableVisibilityProperty);

        private static void OnBindableVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is DataGridColumn column && e.NewValue is Visibility v)
                column.Visibility = v;
        }
    }
}
  • BindingProxy
csharp 复制代码
using System.Windows;

namespace H.Sxb.Modules.Bill.View
{
    // Freezable proxy to expose DataContext into places not in the visual tree (e.g., DataGridColumn)
    public class BindingProxy : Freezable
    {
        public object Data
        {
            get => GetValue(DataProperty);
            set => SetValue(DataProperty, value);
        }

        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register(nameof(Data), typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));

        protected override Freezable CreateInstanceCore() => new BindingProxy();
    }
}

要点

  • DataGridColumn 不在可视树,必须用附加属性设置列的 Visibility。请确保使用命名空间前缀:local:DataGridColumnExtensions.BindableVisibility。
  • 绑定源可用 BindingProxy 暴露的 DataContext(你已加 dgProxy,继续沿用即可)。
  • ConverterParameter 建议逗号分隔(1,2,3)。如果你的 IntInSetToVisibilityConverter 已实现空格分隔,也可保持空格。
  • 若需"按行"显示/隐藏,请改用 DataGridTemplateColumn,在 CellTemplate 内用 DataTrigger 控制单元内容的 Visibility。

了解更多

DataGridColumn

System.Windows.Controls 命名空间 | Microsoft Learn

控件库 - WPF .NET Framework | Microsoft Learn

WPF 介绍 | Microsoft Learn

使用 Visual Studio 创建新应用教程 - WPF .NET | Microsoft Learn

https://github.com/HeBianGu

HeBianGu的个人空间-HeBianGu个人主页-哔哩哔哩视频

GitHub - HeBianGu/WPF-Control: WPF轻量控件和皮肤库

GitHub - HeBianGu/WPF-ControlBase: Wpf封装的自定义控件资源库

相关推荐
做cv的小昊1 小时前
计算机图形学:【Games101】学习笔记05——着色(插值、高级纹理映射)与几何(基本表示方法)
笔记·opencv·学习·计算机视觉·图形渲染·几何学
iconball5 小时前
个人用云计算学习笔记 --24 虚拟化、KVM 基础使用与热迁移实验、VMware ESXi笔记
运维·笔记·学习·云计算
Kiyra5 小时前
WebSocket vs HTTP:为什么 IM 系统选择长连接?
分布式·websocket·网络协议·http·设计模式·系统架构·wpf
是小菜呀!5 小时前
基于深度学习的图像检索系统项目实践
笔记
奕辰杰7 小时前
Netty私人学习笔记
笔记·学习·netty·网络通信·nio
De-Alf8 小时前
Megatron-LM学习笔记(6)Megatron Model Attention注意力与MLA
笔记·学习·算法·ai
polarislove02148 小时前
9.2 自制延迟函数-嵌入式铁头山羊STM32笔记
笔记·stm32·嵌入式硬件
智嵌电子8 小时前
【笔记篇】【硬件基础篇】模拟电子技术基础 (童诗白) 第7章 波形的发生和信号的转换
笔记·嵌入式硬件
要记得喝水8 小时前
某公司C#-WPF面试题-来自nowcoder(含答案和解析)--2
c#·wpf
Gary Studio8 小时前
MPP充电学习笔记
笔记·学习