Hub*_*ert 5 c# wpf datatable binding datagrid
我想使用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')"
Run Code Online (Sandbox Code Playgroud)
我知道这是由于列名中的斜杠(“ /”)被解释为绑定表达式。
我的问题是
这是生成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;
}
Run Code Online (Sandbox Code Playgroud)
这是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>
Run Code Online (Sandbox Code Playgroud)
如评论中所建议,我添加了一个AutoGeneratingColumn处理程序,该处理程序将绑定更改为使用方括号:
private void PaViewAutoGeneratingColumnHandler(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
e.Column = new DataGridTextColumn
{
Binding = new Binding("[" + e.Column.Header + "]"), Header=e.Column.Header
};
}
Run Code Online (Sandbox Code Playgroud)
现在,它适用于“无变化的气候”,但不适用于名为“ EDIP2003 w / o LT,酸化w / o LT,酸化w / o 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]
Run Code Online (Sandbox Code Playgroud)
查看PropertyPath语法的文档,我们可以明白为什么字符串无法映射。
您已经指出并可以修复的第一个是斜杠/:
源遍历(绑定到集合的层次结构)
Run Code Online (Sandbox Code Playgroud)<object Path="propertyName/propertyNameX" .../>此语法中的 / 用于在分层数据源对象内导航,并且支持使用连续 / 字符进入层次结构的多个步骤。
这是通过使用索引器 ( []) 来解决的。
但是,索引器格式支持多个索引器,以逗号分隔:
多个索引器
Run Code Online (Sandbox Code Playgroud)<object Path="[index1,index2...]" .../>或者
Run Code Online (Sandbox Code Playgroud)<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,
};
}
Run Code Online (Sandbox Code Playgroud)