繁体   English   中英

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

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

我想使用DataGrid在C#中显示字符串表。 列名是动态生成的(即在编译时未知)。

这是一个例子:

此处,数字已转换为字符串。

我正在使用DataTable作为包含整个表(行和列标题)的DataGrid的源。 但是,我有一个问题,即“气候变化”列中的值未显示在DataGrid中。 相反,我在控制台上收到以下错误消息

"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')"

我知道这是由于列名中的斜杠(“ /”)被解释为绑定表达式。

我的问题是

  1. 有没有一种方法可以关闭该行为,即将列名解释为绑定表达式? 由于我为DataTable提供了行和列的所有值和标头,因此无需根据列名计算任何数据值。 尽管不存在称为“人类毒性”的属性,但“人类毒性”一栏也没有问题。
  2. 如果我不能使用DataTable作为DataGrid的源来实现上述目标,那么将使用哪种正确的数据结构?

这是生成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;

    }

这是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>

如评论中所建议,我添加了一个AutoGeneratingColumn处理程序,该处理程序将绑定更改为使用方括号:

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

        };
    }

现在,它适用于“无变化的气候”,但不适用于名为“ EDIP2003无LT,酸化无LT,酸化无LT”的列,这是实际使用的示例顾客。 错误消息与以前相同

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] 

查看有关PropertyPath语法的文档,我们可以看到为什么字符串无法映射。

您已经指出并可以解决的第一个是斜杠/

源遍历(绑定到集合层次结构)

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

此语法中的/用于在层次结构数据源对象中导航,并且支持使用连续的/字符进入层次结构的多个步骤。

这是通过使用索引器( [] )修复的。

但是,索引器格式支持多个索引器,以逗号分隔:

多个索引器

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

要么

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

如果给定对象支持多个索引器,则可以按顺序指定这些索引器,类似于数组引用语法。 有问题的对象可以是当前上下文,也可以是包含多索引对象的属性的值。

如果进一步看,可以看到可以使用以下语法对逗号进行转义:

属性路径字符串的转义

对于某些业务对象,您可能会遇到以下情况:属性路径字符串需要转义序列才能正确解析。 转义的需求应该很少见,因为许多这样的字符在通常用于定义业务对象的语言中都具有类似的命名交互问题。

  • 在索引器([])中,脱字符号(^)转义下一个字符。

使用所有这些,我想出了以下解决方案,以在仍然使用自动生成的列的情况下转义所有内容。 可能会过大,但是可以保证正确解释字符串。

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