You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C# WPF中动态创建DataGridView?附自定义数据展示需求

在WPF中动态创建符合行列转换需求的DataGrid

你的核心需求是把扁平的参数列表转换成按参数名分组、后缀作为列的矩阵式展示,自动生成列无法满足这种行列转换的要求,需要通过数据结构转换+动态列生成来实现,以下是具体步骤和完整示例:

1. 先转换数据结构

原始的Parameter列表是每行存储一个「参数名+后缀+值」,我们需要把它转换成每行对应一个参数名、每列对应一个后缀的结构,这里提供两种实现方式:

方式一:强类型ViewModel(适合后缀固定的场景)

如果你的后缀列表(BA1-BA6)是固定的,可以创建对应的数据类:

public class ParameterRow
{
    public string Name { get; set; } // 对应Parameter的Prefix
    public string BA1 { get; set; }
    public string BA2 { get; set; }
    public string BA3 { get; set; }
    public string BA4 { get; set; }
    public string BA5 { get; set; }
    public string BA6 { get; set; }
}

然后编写转换方法,把Mother中的数据映射成List<ParameterRow>:

public List<ParameterRow> ConvertToParameterRows(Mother mother, List<string> prefixes, List<string> suffixes)
{
    var rows = new List<ParameterRow>();
    foreach (var prefix in prefixes)
    {
        var row = new ParameterRow { Name = prefix };
        // 给每个后缀列赋值,无数据则留空
        foreach (var suffix in suffixes)
        {
            var param = mother.parameters.FirstOrDefault(p => p.Prefix == prefix && p.Suffix == suffix);
            switch(suffix)
            {
                case "BA1": row.BA1 = param?.Value ?? string.Empty; break;
                case "BA2": row.BA2 = param?.Value ?? string.Empty; break;
                case "BA3": row.BA3 = param?.Value ?? string.Empty; break;
                case "BA4": row.BA4 = param?.Value ?? string.Empty; break;
                case "BA5": row.BA5 = param?.Value ?? string.Empty; break;
                case "BA6": row.BA6 = param?.Value ?? string.Empty; break;
            }
        }
        rows.Add(row);
    }
    return rows;
}

方式二:动态类型(适合后缀动态变化的场景)

如果后缀列表可能随时修改,用ExpandoObject可以避免频繁修改ViewModel:

public List<dynamic> ConvertToDynamicRows(Mother mother, List<string> prefixes, List<string> suffixes)
{
    var rows = new List<dynamic>();
    foreach (var prefix in prefixes)
    {
        dynamic row = new ExpandoObject();
        row.Name = prefix;
        var dict = (IDictionary<string, object>)row;
        // 动态添加后缀对应的属性
        foreach (var suffix in suffixes)
        {
            var param = mother.parameters.FirstOrDefault(p => p.Prefix == prefix && p.Suffix == suffix);
            dict[suffix] = param?.Value ?? string.Empty;
        }
        rows.Add(row);
    }
    return rows;
}

2. 动态生成DataGrid列

修改XAML,关闭自动生成列,给DataGrid命名以便后台操作:

<DataTemplate DataType="{x:Type local:Mother}">
    <DataGrid x:Name="parameterGrid" AutoGenerateColumns="False" />
</DataTemplate>

然后在后台代码中(比如窗口Loaded事件、DataTemplate加载事件)动态创建列:

private void SetupDataGridColumns(List<string> suffixes)
{
    // 添加第一列:参数名列
    parameterGrid.Columns.Add(new DataGridTextColumn
    {
        Header = "Name",
        Binding = new Binding("Name"),
        Width = new DataGridLength(1.5, DataGridLengthUnitType.Star) // 占比更大,方便显示参数名
    });

    // 循环添加每个后缀对应的列
    foreach (var suffix in suffixes)
    {
        parameterGrid.Columns.Add(new DataGridTextColumn
        {
            Header = suffix,
            Binding = new Binding(suffix),
            Width = new DataGridLength(1, DataGridLengthUnitType.Star)
        });
    }
}

3. 绑定数据源到DataGrid

最后把转换后的数据集绑定到DataGrid:

// 模拟初始化数据
var mother = new Mother();
mother.parameters.AddRange(new List<Parameter>
{
    new Parameter { Prefix = "Parameter1", Suffix = "BA1", Value = "55" },
    new Parameter { Prefix = "Parameter1", Suffix = "BA2", Value = "58" },
    new Parameter { Prefix = "Parameter1", Suffix = "BA3", Value = "1" },
    new Parameter { Prefix = "Parameter1", Suffix = "BA4", Value = "77" },
    new Parameter { Prefix = "Parameter1", Suffix = "BA5", Value = "7889" },
    new Parameter { Prefix = "Parameter1", Suffix = "BA6", Value = "100" },
    new Parameter { Prefix = "Parameter2", Suffix = "BA1", Value = "7" },
    new Parameter { Prefix = "Parameter2", Suffix = "BA2", Value = "44" }
});

var prefixes = new List<string> { "Parameter1", "Parameter2", "Parameter3", "Parameter4" };
var suffixes = new List<string> { "BA1", "BA2", "BA3", "BA4", "BA5", "BA6" };

// 转换数据(二选一)
var rows = ConvertToParameterRows(mother, prefixes, suffixes);
// var rows = ConvertToDynamicRows(mother, prefixes, suffixes);

// 设置列和数据源
SetupDataGridColumns(suffixes);
parameterGrid.ItemsSource = rows;

完整可运行示例

如果是在Window中使用,完整代码如下:

MainWindow.xaml

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp"
        Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
    <Grid>
        <DataGrid x:Name="parameterGrid" AutoGenerateColumns="False" />
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace WpfApp
{
    public class Parameter
    {
        public string Prefix { get; set; }
        public string Suffix { get; set; }
        public string Value { get; set; }
    }

    public class Mother
    {
        public List<Parameter> parameters { get; set; } = new List<Parameter>();
    }

    public class ParameterRow
    {
        public string Name { get; set; }
        public string BA1 { get; set; }
        public string BA2 { get; set; }
        public string BA3 { get; set; }
        public string BA4 { get; set; }
        public string BA5 { get; set; }
        public string BA6 { get; set; }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // 模拟填充数据
            var mother = new Mother();
            mother.parameters.AddRange(new List<Parameter>
            {
                new Parameter { Prefix = "Parameter1", Suffix = "BA1", Value = "55" },
                new Parameter { Prefix = "Parameter1", Suffix = "BA2", Value = "58" },
                new Parameter { Prefix = "Parameter1", Suffix = "BA3", Value = "1" },
                new Parameter { Prefix = "Parameter1", Suffix = "BA4", Value = "77" },
                new Parameter { Prefix = "Parameter1", Suffix = "BA5", Value = "7889" },
                new Parameter { Prefix = "Parameter1", Suffix = "BA6", Value = "100" },
                new Parameter { Prefix = "Parameter2", Suffix = "BA1", Value = "7" },
                new Parameter { Prefix = "Parameter2", Suffix = "BA2", Value = "44" }
            });

            var prefixes = new List<string> { "Parameter1", "Parameter2", "Parameter3", "Parameter4" };
            var suffixes = new List<string> { "BA1", "BA2", "BA3", "BA4", "BA5", "BA6" };

            // 转换数据并绑定
            var rows = ConvertToParameterRows(mother, prefixes, suffixes);
            SetupDataGridColumns(suffixes);
            parameterGrid.ItemsSource = rows;
        }

        private List<ParameterRow> ConvertToParameterRows(Mother mother, List<string> prefixes, List<string> suffixes)
        {
            var rows = new List<ParameterRow>();
            foreach (var prefix in prefixes)
            {
                var row = new ParameterRow { Name = prefix };
                foreach (var suffix in suffixes)
                {
                    var param = mother.parameters.FirstOrDefault(p => p.Prefix == prefix && p.Suffix == suffix);
                    switch (suffix)
                    {
                        case "BA1": row.BA1 = param?.Value ?? string.Empty; break;
                        case "BA2": row.BA2 = param?.Value ?? string.Empty; break;
                        case "BA3": row.BA3 = param?.Value ?? string.Empty; break;
                        case "BA4": row.BA4 = param?.Value ?? string.Empty; break;
                        case "BA5": row.BA5 = param?.Value ?? string.Empty; break;
                        case "BA6": row.BA6 = param?.Value ?? string.Empty; break;
                    }
                }
                rows.Add(row);
            }
            return rows;
        }

        private void SetupDataGridColumns(List<string> suffixes)
        {
            parameterGrid.Columns.Add(new DataGridTextColumn
            {
                Header = "Name",
                Binding = new Binding("Name"),
                Width = new DataGridLength(1.5, DataGridLengthUnitType.Star)
            });

            foreach (var suffix in suffixes)
            {
                parameterGrid.Columns.Add(new DataGridTextColumn
                {
                    Header = suffix,
                    Binding = new Binding(suffix),
                    Width = new DataGridLength(1, DataGridLengthUnitType.Star)
                });
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者MadaraUtchi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 22:09:15