带点的DataTable列名为什么不适合WPF的DataGrid控件?

w7t8yxp5  于 2023-10-22  发布在  其他
关注(0)|答案(4)|浏览(154)

运行这个,并感到困惑:

<Window x:Class="Data_Grids.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <DataGrid
        Name="r1"
              ItemsSource="{Binding Path=.}">
        </DataGrid>
        <DataGrid
        Name="r2"
              ItemsSource="{Binding Path=.}">
        </DataGrid>
    </StackPanel>
</Window>

代码隐藏:

using System.Data;
using System.Windows;

namespace Data_Grids
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataTable dt1, dt2;
            dt1 = new DataTable();
            dt2 = new DataTable();
            dt1.Columns.Add("a-name", typeof(string));
            dt1.Columns.Add("b-name", typeof(string));
            dt1.Rows.Add(new object[] { 1, "Hi" });
            dt1.Rows.Add(new object[] { 2, "Hi" });
            dt1.Rows.Add(new object[] { 3, "Hi" });
            dt1.Rows.Add(new object[] { 4, "Hi" });
            dt1.Rows.Add(new object[] { 5, "Hi" });
            dt1.Rows.Add(new object[] { 6, "Hi" });
            dt1.Rows.Add(new object[] { 7, "Hi" });
            dt2.Columns.Add("a.name", typeof(string));
            dt2.Columns.Add("b.name", typeof(string));
            dt2.Rows.Add(new object[] { 1, "Hi" });
            dt2.Rows.Add(new object[] { 2, "Hi" });
            dt2.Rows.Add(new object[] { 3, "Hi" });
            dt2.Rows.Add(new object[] { 4, "Hi" });
            dt2.Rows.Add(new object[] { 5, "Hi" });
            dt2.Rows.Add(new object[] { 6, "Hi" });
            dt2.Rows.Add(new object[] { 7, "Hi" });
            r1.DataContext = dt1;
            r2.DataContext = dt2;
        }
    }
}

我来告诉你会发生什么。顶部的数据网格填充有列标题和数据。底部的数据网格有 * 列标题 *,但所有行都是空白的。

xfb7svmp

xfb7svmp1#

您可以将AutoGenerateColumns设置为true,并添加一个eventhandler来处理任何句点(或其他特殊字符):

<DataGrid
          Name="r2"
          ItemsSource="{Binding Path=.}"
          AutoGeneratingColumn="r2_AutoGeneratingColumn">
    </DataGrid>

代码隐藏:

private void r2_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    if (e.PropertyName.Contains('.') && e.Column is DataGridBoundColumn)
    {
        DataGridBoundColumn dataGridBoundColumn = e.Column as DataGridBoundColumn;
        dataGridBoundColumn.Binding = new Binding("[" + e.PropertyName + "]");
    }
}

这在MVVM场景中对我来说效果更好。

aiqt4smr

aiqt4smr2#

绑定路径解析器错误地解释了第二个表的列名中的句号字符。在此示例运行时查看调试输出,您可以看到自动生成的列已绑定到'a'和'b',而不是'a.name'和'b.name'

System.Windows.Data Error: 40 : BindingExpression path error: 'a' property not found on 'object' ''DataRowView' ... etc.
System.Windows.Data Error: 40 : BindingExpression path error: 'b' property not found on 'object' ''DataRowView' ... etc.

在绑定路径中有许多具有特殊含义的不同字符,包括句号(“.”),斜杠(“/”),方括号(“[”,“]”)和括号(“(”,“)”),括号会导致您的应用程序崩溃。这些特殊字符可以通过用方括号将绑定路径括起来进行转义。有关路径和字符转义的更多信息,请参见Binding Declarations Overview
要解决这个问题,您必须设置AutoGenerateColumns=“False”并在xaml中指定列绑定:

<DataGrid
    x:Name="r2"
          ItemsSource="{Binding .}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="a.name" Binding="{Binding Path=[a.name]}" />
            <DataGridTextColumn Header="b.name" Binding="{Binding Path=[b.name]}" />
        </DataGrid.Columns>
    </DataGrid>

或者在后面的代码中编程

r2.AutoGenerateColumns = false;
        foreach( DataColumn column in dt2.Columns )
        {
            var gridColumn = new DataGridTextColumn()
            {
                Header = column.ColumnName,
                Binding = new Binding( "[" + column.ColumnName + "]" )
            };

            r2.Columns.Add( gridColumn );
        }

        r2.DataContext = dt2;
pepwfjgg

pepwfjgg3#

FULL STOP(句号/点)字符不起作用。
即使用x\002E逃跑也没有用。
下面是使用中间点字符的折衷方法:

dt1.Columns.Add("a\x00B7name", typeof(string));  
dt1.Columns.Add("b\x00B7name", typeof(string));
hrysbysz

hrysbysz4#

我最终使用了替代一个点的领导者,它工作得很好。我从一个XML文件导入数据,而不是在代码中到处使用string.replace(".","\x2024");,这样更容易更改导入文件。
之前

<Components Description="Thru Tee" Size="0.5" Kv="0.54" />

<Components Description="Thru Tee" Size="0&#x2024;5" Kv="0.54" />

相关问题