简体   繁体   English

列名称中的C#DataTable DataGrid特殊字符“ /”(斜杠)

[英]C# DataTable DataGrid special character “/” (slash) in column names

I would like to display a table of strings in C# using a DataGrid. 我想使用DataGrid在C#中显示字符串表。 The column names are dynamically generated (ie not known at compile time). 列名是动态生成的(即在编译时未知)。

Here is an example: 这是一个例子:

Here, the numbers have been converted to strings. 此处,数字已转换为字符串。

I am using a DataTable as the source for the DataGrid which contains the whole table (rows and column headers). 我正在使用DataTable作为包含整个表(行和列标题)的DataGrid的源。 However, I have the problem that the values in column "climate w/change" are not shown in the DataGrid. 但是,我有一个问题,即“气候变化”列中的值未显示在DataGrid中。 Instead I get the following error message on the Console 相反,我在控制台上收到以下错误消息

"BindingExpression path error: 'climate  w' property not found on 'object' 
''DataRowView' (HashCode=22429696)'. BindingExpression:Path=climate  
w/change; DataItem='DataRowView' (HashCode=22429696); target element is 
'TextBlock' (Name=''); target property is 'Text' (type 'String')"

I understand that this is due to the slash ("/") in the column name which is interpreted as a binding expression. 我知道这是由于列名中的斜杠(“ /”)被解释为绑定表达式。

My questions are 我的问题是

  1. Is there a way to switch off that behavior, ie that column names are interpreted as binding expressions? 有没有一种方法可以关闭该行为,即将列名解释为绑定表达式? Since I provide a DataTable with all values and headers for the rows and columns, none of the data values need to be computed based on the column name. 由于我为DataTable提供了行和列的所有值和标头,因此无需根据列名计算任何数据值。 Also the column "human toxicity" has no problems although there does not exists a property called HumanToxicity. 尽管不存在称为“人类毒性”的属性,但“人类毒性”一栏也没有问题。
  2. If I cannot use DataTable as the source for the DataGrid to achieve the above, which is the correct data structure to be used? 如果我不能使用DataTable作为DataGrid的源来实现上述目标,那么将使用哪种正确的数据结构?

Here is the code to generate the DataTable. 这是生成DataTable的代码。

    public DataTable PaValues { get; set; }

    private void CreateDataSet()
    {
        var dt = new DataTable("Perturbation Analysis");
        List<String> ics = _perturbationAnalysis.ImpactCatagories();
        dt.Columns.Add("Parameters");

        foreach (var ic in ics)
        {
            dt.Columns.Add(Sanatize(ic));
        }
        foreach (var parameter in _perturbationAnalysis.ParameterNames())
        {
            var dr = dt.NewRow();
            dr[0] = parameter;
            for (int i = 0; i < ics.Count; i++)
            {
                dr[i+1] = _perturbationAnalysis[parameter, ics[i]].ToString();
            }
            dt.Rows.Add(dr);
        }
        PaValues = dt;
    }

    private string Sanatize(string ic)
    {
        //return ic.Replace("/", "[/]").Replace("[", "").Replace("]", "").Replace(".", " ");
        //return "[" + ic + "]";
        return ic;

    }

Here is the excerpt from the XAML file 这是XAML文件的摘录

            <DataGrid
                x:Name="PAGrid"
                CanUserAddRows="False" 
                CanUserDeleteRows="False"
                ClipboardCopyMode="IncludeHeader"
                FrozenColumnCount="1"
                ItemsSource="{Binding Path=PaValues,UpdateSourceTrigger=PropertyChanged}"
                Style="{StaticResource DataGridStyle}"
                IsReadOnly="True">
            </DataGrid>

As proposed in the comments, I have added an AutoGeneratingColumn handler, which changes the binding to use square brackets: 如评论中所建议,我添加了一个AutoGeneratingColumn处理程序,该处理程序将绑定更改为使用方括号:

    private void PaViewAutoGeneratingColumnHandler(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        e.Column = new DataGridTextColumn
        {
            Binding = new Binding("[" + e.Column.Header + "]"), Header=e.Column.Header

        };
    }

It now works fine for "climate w/change", but it does not work for a column named "EDIP2003 w/o LT, acidification w/o LT, acidification w/o LT", which is a real life example used by the customer. 现在,它适用于“无变化的气候”,但不适用于名为“ EDIP2003无LT,酸化无LT,酸化无LT”的列,这是实际使用的示例顾客。 The error message is the same as before 错误消息与以前相同

BindingExpression path error: '[]' property not found on 'object' ''DataRowView' (HashCode=56876317)'. 
BindingExpression:Path=[EDIP2003 w/o LT, acidification w/o LT, acidification w/o LT] 

Looking at the documentation on PropertyPath syntax , we can see why the strings fail to map. 查看有关PropertyPath语法的文档,我们可以看到为什么字符串无法映射。

The first one, which you already pointed out and could fix, is the slash / : 您已经指出并可以解决的第一个是斜杠/

Source Traversal (Binding to Hierarchies of Collections) 源遍历(绑定到集合层次结构)

 <object Path="propertyName/propertyNameX" .../> 

The / in this syntax is used to navigate within a hierarchical data source object, and multiple steps into the hierarchy with successive / characters are supported. 此语法中的/用于在层次结构数据源对象中导航,并且支持使用连续的/字符进入层次结构的多个步骤。

This is fixed by using an indexer ( [] ). 这是通过使用索引器( [] )修复的。

However, the indexer format supports multiple indexers, separated by comma: 但是,索引器格式支持多个索引器,以逗号分隔:

Multiple Indexers 多个索引器

 <object Path="[index1,index2...]" .../> 

or 要么

 <object Path="propertyName[index,index2...]" .../> 

If a given object supports multiple indexers, those indexers can be specified in order, similar to an array referencing syntax. 如果给定对象支持多个索引器,则可以按顺序指定这些索引器,类似于数组引用语法。 The object in question can be either the current context or the value of a property that contains a multiple index object. 有问题的对象可以是当前上下文,也可以是包含多索引对象的属性的值。

If we look further, we can see that we can escape the comma using the following syntax: 如果进一步看,可以看到可以使用以下语法对逗号进行转义:

Escapes for Property Path Strings 属性路径字符串的转义

For certain business objects, you might encounter a case where the property path string requires an escape sequence in order to parse correctly. 对于某些业务对象,您可能会遇到以下情况:属性路径字符串需要转义序列才能正确解析。 The need to escape should be rare, because many of these characters have similar naming-interaction issues in languages that would typically be used to define the business object. 转义的需求应该很少见,因为许多这样的字符在通常用于定义业务对象的语言中都具有类似的命名交互问题。

  • Inside indexers ([ ]), the caret character (^) escapes the next character. 在索引器([])中,脱字符号(^)转义下一个字符。

Using all of this, I came up with the following solution to escape everything while still using auto-generated columns. 使用所有这些,我想出了以下解决方案,以在仍然使用自动生成的列的情况下转义所有内容。 It might be overkill, but it guarantees that the string is interpreted correctly. 可能会过大,但是可以保证正确解释字符串。

private void PaViewAutoGeneratingColumnHandler(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    var columnName = (string)e.Column.Header;

    // We'll build a string with escaped characters.
    // The capacity is the length times 2 (for the carets),
    // plus 2 for the square brackets.
    // This is not optimized for multi-character glyphs, like emojis

    var bindingBuilder = new StringBuilder(columnName.Length * 2 + 2);

    bindingBuilder.Append('[');
    foreach (var c in columnName)
    {
        bindingBuilder.Append('^');
        bindingBuilder.Append(c);
    }
    bindingBuilder.Append(']');

    e.Column = new DataGridTextColumn
    {
        Binding = new Binding(bindingBuilder.ToString()),
        Header = e.Column.Header,
    };
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM