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

WPF DataGrid绑定类变量列异常及单元格值获取问题求助

WPF动态DataGrid功能问题修复方案

问题1:第一个DataGrid自动生成额外列

原因:DataGrid默认AutoGenerateColumns="True",手动添加列后会自动生成绑定对象的所有公共属性列(即原代码中的rowTracks列)。
修复:在XAML的两个DataGrid控件中添加AutoGenerateColumns="False",禁止自动生成列。

问题2:单元格输入值同步到所有单元格

原因:原代码所有列都绑定到dTracks类的同一个rowTracks属性,所有单元格共享同一数据源属性,导致输入值同步变化。
修复:改用DataTable作为第一个DataGrid的数据源,动态创建对应track数量的独立列,每个单元格对应DataTable的独立字段,确保值互不影响。

问题3:Set_Segments无法获取第一个网格值,列数异常

原因:

  • 原代码将ObservableCollection<dTracks>作为数据源,却尝试转换为DataRowView,类型转换失败导致无输出;
  • 循环逻辑错误,dg_tracks.Items.Count - 1使得循环条件不满足,无法执行取值操作;
  • 列数多1是因为数据源结构与列绑定不匹配,改用DataTable后可直接准确获取列数。
    修复:
  • 用DataTable存储第一个网格的输入值,直接从DataRow读取单元格数据;
  • 修正循环逻辑,正确遍历DataTable的行和列;
  • 第二个DataGrid根据第一个网格的输入值,为每个track创建对应行数的列,不足行数的单元格留空。

修改后的XAML代码

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="500">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="204*"/>
            <ColumnDefinition Width="69*"/>
            <ColumnDefinition Width="227*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="40*"/>
            <RowDefinition Height="160*"/>
        </Grid.RowDefinitions>

        <Label Content="Number of tracks" Grid.Row="0" Grid.Column="0"></Label>
        <TextBox x:Name="txt_tracks" Grid.Row="0" Grid.Column="1" Width="50" Height="20"/>
        <Button x:Name="bt_settracks" Grid.Row="0" Grid.Column="2" Content="Set tracks" Width="100" Height="20" Click="bt_settracks_Click"/>

        <ScrollViewer Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <DataGrid x:Name="dgrid_tracks" CanUserAddRows="False" AutoGenerateColumns="False"></DataGrid>
        </ScrollViewer>

        <Button x:Name="bt_setsegments" Content="Set segments" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" Width="100" Height="20" Click="bt_setsegments_Click"/>

        <ScrollViewer Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <DataGrid x:Name="dgrid_segments" CanUserAddRows="False" AutoGenerateColumns="False"></DataGrid>
        </ScrollViewer>

    </Grid>
</Window>

修改后的C#代码

using System;
using System.Data;
using System.Windows;
using System.Windows.Controls;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        private DataTable trackSegmentsTable;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Set_Tracks(DataGrid dgrid, ushort NUM_TRACKS)
        {
            dgrid.Columns.Clear();
            trackSegmentsTable = new DataTable();

            // 创建对应track数量的列
            for (ushort i = 0; i < NUM_TRACKS; i++)
            {
                string columnName = $"Track_{i}";
                trackSegmentsTable.Columns.Add(columnName, typeof(ushort));

                // 添加DataGrid列
                DataGridTextColumn newTrackColumn = new DataGridTextColumn();
                newTrackColumn.Header = $"Track {i}";
                newTrackColumn.Binding = new Binding(columnName);
                newTrackColumn.Width = 100;
                dgrid.Columns.Add(newTrackColumn);
            }

            // 添加一行用于输入
            trackSegmentsTable.Rows.Add();
            dgrid.ItemsSource = trackSegmentsTable.DefaultView;
        }

        private void Set_Segments(DataGrid dg_segments, ushort NUM_TRACKS)
        {
            dg_segments.Columns.Clear();
            DataTable segmentsTable = new DataTable();

            // 获取每个track的segment数量
            ushort[] segmentCounts = new ushort[NUM_TRACKS];
            for (int i = 0; i < NUM_TRACKS; i++)
            {
                string columnName = $"Track_{i}";
                // 读取输入值,默认0
                if (trackSegmentsTable.Rows[0][i] != DBNull.Value)
                    segmentCounts[i] = Convert.ToUInt16(trackSegmentsTable.Rows[0][i]);
                else
                    segmentCounts[i] = 0;

                // 创建第二个DataGrid的列
                segmentsTable.Columns.Add($"Track {i}", typeof(string));
                DataGridTextColumn segmentColumn = new DataGridTextColumn();
                segmentColumn.Header = $"Track {i}";
                segmentColumn.Binding = new Binding($"Track {i}");
                segmentColumn.Width = 100;
                dg_segments.Columns.Add(segmentColumn);
            }

            // 计算最大行数,确保所有列的行都能显示
            int maxRows = 0;
            foreach (ushort count in segmentCounts)
            {
                if (count > maxRows)
                    maxRows = count;
            }

            // 添加行,每个track对应行填充,不足的留空
            for (int row = 0; row < maxRows; row++)
            {
                DataRow newRow = segmentsTable.NewRow();
                for (int col = 0; col < NUM_TRACKS; col++)
                {
                    if (row < segmentCounts[col])
                        newRow[$"Track {col}"] = $"Segment {row + 1}";
                    else
                        newRow[$"Track {col}"] = DBNull.Value;
                }
                segmentsTable.Rows.Add(newRow);
            }

            dg_segments.ItemsSource = segmentsTable.DefaultView;
        }

        private void bt_settracks_Click(object sender, RoutedEventArgs e)
        {
            if (ushort.TryParse(txt_tracks.Text, out ushort numTracks))
            {
                Set_Tracks(dgrid_tracks, numTracks);
            }
            else
            {
                MessageBox.Show("请输入有效的数字");
            }
        }

        private void bt_setsegments_Click(object sender, RoutedEventArgs e)
        {
            if (ushort.TryParse(txt_tracks.Text, out ushort numTracks))
            {
                Set_Segments(dgrid_segments, numTracks);
            }
            else
            {
                MessageBox.Show("请输入有效的数字");
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 13:17:46