WPF DataGrid绑定含无效属性路径列名的DataView问题
Ah, I've run into this exact issue before! The problem stems from how WPF's DataGrid auto-generates columns when bound to a DataView: it tries to use the column name as a property path, but DataRowView doesn't expose columns as properties—you access values via its indexer instead. When your column name has characters that are invalid in a property path (spaces, brackets, dots, etc.), the auto-generated binding breaks because it can't resolve that path.
The Simple Fix: Adjust the Binding in AutoGeneratingColumn
You don't need custom wrappers or fancy PropertyDescriptor workarounds. Just tweak the binding in the AutoGeneratingColumn event to use the indexer syntax, which properly handles special characters. Here's how to update your event handler:
private void DataGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { // Keep the original column name as the header (so users see the correct label) e.Column.Header = e.PropertyName; // Replace the broken auto-generated binding with an indexer-based one if (e.Column is DataGridTextColumn textColumn) { // Use the indexer syntax with the column name wrapped in quotes textColumn.Binding = new Binding($"[\"{e.PropertyName}\"]"); } // Handle other column types if you use them (e.g., checkboxes) else if (e.Column is DataGridCheckBoxColumn checkBoxColumn) { checkBoxColumn.Binding = new Binding($"[\"{e.PropertyName}\"]"); } }
Why This Works
- The binding path
["Column Name With Special Chars"]tells WPF to use DataRowView's indexer with the exact column name string, bypassing property path validation entirely. - This approach works even when you have no control over the source DataTable's column names, since you're adapting the binding at column generation time.
Optional: Use DataColumn.Caption for Headers
If you want to separate the internal column name (with special chars) from the user-facing header, you can fetch the Caption property from your DataTable instead:
private void DataGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { // Fetch the corresponding DataColumn to get the Caption var targetColumn = TestData.Table.Columns[e.PropertyName]; e.Column.Header = string.IsNullOrEmpty(targetColumn.Caption) ? targetColumn.ColumnName : targetColumn.Caption; // Update the binding as before if (e.Column is DataGridTextColumn textColumn) { textColumn.Binding = new Binding($"[\"{e.PropertyName}\"]"); } }
内容的提问来源于stack exchange,提问作者Patrick Kursawe




