如何在WPF C#的DataGrid中扁平化显示多组坐标数据?
可以实现,以下是两种可行方案
你的需求完全可以在WPF C#中实现,因为仅需展示无需编辑,不用处理复杂的编辑逻辑,下面提供两种直接落地的方案:
方案1:拼接多行文本快速实现
这种方法最简单,直接把每个坐标集的X/Y/Z和表头拼接成带换行的文本,用等宽字体保证对齐:
步骤1:定义展示模型
public class CoordinateDisplayModel { public string A { get; set; } public string B { get; set; } public string C { get; set; } public string Z50Display { get; set; } public string Z51Display { get; set; } public string LatLongDisplay { get; set; } }
步骤2:构造数据源
var displayData = new List<CoordinateDisplayModel> { new CoordinateDisplayModel { A = "???", B = "???", C = "???", Z50Display = $"X Y Z\n123456 4567890 445.3", Z51Display = $"X Y Z\n234567 9876543 445.3", LatLongDisplay = $"X Y Z\n112.45 83.250 NULL" } }; // 绑定到DataGrid dataGrid.ItemsSource = displayData;
步骤3:XAML定义列
<DataGrid x:Name="dataGrid" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="A" Binding="{Binding A}"/> <DataGridTextColumn Header="B" Binding="{Binding B}"/> <DataGridTextColumn Header="C" Binding="{Binding C}"/> <DataGridTemplateColumn Header="Z50"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Z50Display}" TextWrapping="NoWrap" FontFamily="Courier New"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="Z51"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Z51Display}" TextWrapping="NoWrap" FontFamily="Courier New"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="LatLong"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding LatLongDisplay}" TextWrapping="NoWrap" FontFamily="Courier New"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
等宽字体(Courier New)能让X/Y/Z的数值和表头完美对齐,快速达到预期效果。
方案2:嵌套DataGrid实现规整表格样式
如果想要更贴近原生表格的结构,每个坐标列内部显示独立的X/Y/Z子表头和数据,可以在单元格内嵌套小型DataGrid:
步骤1:定义数据模型
// 单个坐标模型 public class Coordinate { public string X { get; set; } public string Y { get; set; } public string Z { get; set; } } // 主数据模型 public class MainDisplayModel { public string A { get; set; } public string B { get; set; } public string C { get; set; } public Coordinate Z50 { get; set; } public Coordinate Z51 { get; set; } public Coordinate LatLong { get; set; } }
步骤2:写一个转换器(把单个坐标转成集合)
因为DataGrid需要绑定集合类型的数据源,所以需要把单个Coordinate对象转成列表:
public class CoordinateToListConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is Coordinate coord) { return new List<Coordinate> { coord }; } return null; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
步骤3:构造并绑定数据源
var mainData = new List<MainDisplayModel> { new MainDisplayModel { A = "???", B = "???", C = "???", Z50 = new Coordinate { X = "123456", Y = "4567890", Z = "445.3" }, Z51 = new Coordinate { X = "234567", Y = "9876543", Z = "445.3" }, LatLong = new Coordinate { X = "112.45", Y = "83.250", Z = "NULL" } } }; dataGrid.ItemsSource = mainData;
步骤4:XAML定义列(包含嵌套DataGrid)
先在窗口资源中声明转换器:
<Window.Resources> <local:CoordinateToListConverter x:Key="CoordinateToListConverter"/> </Window.Resources>
然后定义主DataGrid的列:
<DataGrid x:Name="dataGrid" AutoGenerateColumns="False" RowHeaderWidth="0"> <DataGrid.Columns> <DataGridTextColumn Header="A" Binding="{Binding A}"/> <DataGridTextColumn Header="B" Binding="{Binding B}"/> <DataGridTextColumn Header="C" Binding="{Binding C}"/> <DataGridTemplateColumn Header="Z50"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <DataGrid ItemsSource="{Binding Z50, Converter={StaticResource CoordinateToListConverter}}" AutoGenerateColumns="False" HeadersVisibility="Column" BorderThickness="0" RowHeaderWidth="0"> <DataGrid.Columns> <DataGridTextColumn Header="X" Binding="{Binding X}" Width="Auto"/> <DataGridTextColumn Header="Y" Binding="{Binding Y}" Width="Auto"/> <DataGridTextColumn Header="Z" Binding="{Binding Z}" Width="Auto"/> </DataGrid.Columns> </DataGrid> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <!-- 复制Z50的列模板,修改为Z51和LatLong的绑定即可 --> <DataGridTemplateColumn Header="Z51"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <DataGrid ItemsSource="{Binding Z51, Converter={StaticResource CoordinateToListConverter}}" AutoGenerateColumns="False" HeadersVisibility="Column" BorderThickness="0" RowHeaderWidth="0"> <DataGrid.Columns> <DataGridTextColumn Header="X" Binding="{Binding X}" Width="Auto"/> <DataGridTextColumn Header="Y" Binding="{Binding Y}" Width="Auto"/> <DataGridTextColumn Header="Z" Binding="{Binding Z}" Width="Auto"/> </DataGrid.Columns> </DataGrid> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="LatLong"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <DataGrid ItemsSource="{Binding LatLong, Converter={StaticResource CoordinateToListConverter}}" AutoGenerateColumns="False" HeadersVisibility="Column" BorderThickness="0" RowHeaderWidth="0"> <DataGrid.Columns> <DataGridTextColumn Header="X" Binding="{Binding X}" Width="Auto"/> <DataGridTextColumn Header="Y" Binding="{Binding Y}" Width="Auto"/> <DataGridTextColumn Header="Z" Binding="{Binding Z}" Width="Auto"/> </DataGrid.Columns> </DataGrid> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
这种方案的样式更规整,完全符合你预期的表格结构。
内容的提问来源于stack exchange,提问作者Quentin
相关产品推荐
相关产品推荐

