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
相关产品推荐
相关产品推荐

