This question already has an answer here:
-
What is it about DataTable Column Names with dots that makes them unsuitable for WPF's DataGrid control?
4 answers
I have a WPF Datagrid in my application where I set the value of the ItemSource to the DefaultView of a DataTable that I have constructed. The problem lies in the fact that whenever I set the ColumnName of one of the columns in my DataTable to a string that includes '/' the header shows up in the DataGrid control but the values do not. How can I get around this?
This is the same table with the '/' replaced with '-'
as an aside this also appears to happen with headers that have a '.' in them. So any decimal will cause the same behavior.
My grid is defined as
<DataGrid x:Name="dgLFKPI" />
and I am setting the value in code behind (yes it should be in a viewmodel and MVVM but it is a legacy app that is slowly moving that way).
dgLFKPI.ItemsSource = dt.DefaultView;
The special characters in the column names are incorrectly parsed by the binding path parser.
So a column binding to 3/4
is actually only binding to the property 3
, and not the property 3/4
. (The same thing with the .
binding)
You'll probably see binding errors in the debug window while this is running that should say the same sort of thing.
System.Windows.Data Error: 40 : BindingExpression path error:
'3' property not found on 'object' ''DataRowView'
According to this answer
There are a number of different characters which have special meaning
in a binding path including full stop ('.'), slash ('/'), square
brackets ('[',']') and parenthesis ('(',')'), the parenthesis will
cause your app to crash. These special characters can be escaped by
surrounding the binding path with square brackets. More information
about paths and character escaping can be found in the [Binding
Declarations Overview][2]
That linked question also contains a good solution for dealing with grids that want to use auto-generated columns.
Use the AutoGeneratingColumn
event, and manually create the bindings for columns with these special characters in their name to escape them using the square brackets.
<DataGrid x:Name="dgLFKPI"
AutoGeneratingColumn="dgLFKPI_AutoGeneratingColumn" />
private void dgLFKPI_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyName.Contains('/') && e.Column is DataGridBoundColumn)
{
var col = e.Column as DataGridBoundColumn;
col.Binding = new Binding(string.Format("[{0}]", e.PropertyName));
}
}
You need to set the columns specifically, then set the Header
value of the column to your fraction value.
<DataGrid x:Name="dgLFKPI">
<dg:DataGridTextColumn Header="0" Width="50" Binding="{Binding <columnname>}" />
<dg:DataGridTextColumn Header="1/4" Width="50" Binding="{Binding <columnname>}" />
...
</DataGrid>
Alternatively, you could build it up in the codebehind:
var col = new DataGridTextColumn{
Header = "1/4";
Binding = new Binding("<columnname>")};
dataGrid1.Columns.Add(col);