【笔记】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封装的自定义控件资源库

相关推荐
_李小白5 小时前
【OPENGL ES 3.0 学习笔记】第一天:认识渲染管道
笔记·学习
bnsarocket6 小时前
Verilog和FPGA的自学笔记4——多路选择器(always语句)
笔记·fpga开发·编程·verilog·自学·硬件编程
Pota-to成长日记7 小时前
Redisson 看门狗机制深度解析:分布式锁的守护者
分布式·wpf
为java加瓦8 小时前
分布式单例模式在微服务架构中的关键作用与实践
wpf
c#上位机9 小时前
wpf之Ellipse控件
wpf
你也渴望鸡哥的力量么9 小时前
爬虫学习笔记
笔记·爬虫·学习
c#上位机9 小时前
wpf之GroupBox
c#·wpf
日更嵌入式的打工仔9 小时前
InitLWIP() 初始化
笔记·嵌入式硬件·学习
峰顶听歌的鲸鱼9 小时前
38.Shell脚本编程2
linux·运维·服务器·笔记·学习方法