Что такое в именах столбцов DataTable с точками, что делает их неподходящими для элемента управления DataGrid WPF? - PullRequest
14 голосов
/ 31 мая 2010

Запустите это, и запутайтесь:

<Window x:Class="Data_Grids.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <DataGrid
        Name="r1"
              ItemsSource="{Binding Path=.}">
        </DataGrid>
        <DataGrid
        Name="r2"
              ItemsSource="{Binding Path=.}">
        </DataGrid>
    </StackPanel>
</Window>

Codebehind:

using System.Data;
using System.Windows;

namespace Data_Grids
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataTable dt1, dt2;
            dt1 = new DataTable();
            dt2 = new DataTable();
            dt1.Columns.Add("a-name", typeof(string));
            dt1.Columns.Add("b-name", typeof(string));
            dt1.Rows.Add(new object[] { 1, "Hi" });
            dt1.Rows.Add(new object[] { 2, "Hi" });
            dt1.Rows.Add(new object[] { 3, "Hi" });
            dt1.Rows.Add(new object[] { 4, "Hi" });
            dt1.Rows.Add(new object[] { 5, "Hi" });
            dt1.Rows.Add(new object[] { 6, "Hi" });
            dt1.Rows.Add(new object[] { 7, "Hi" });
            dt2.Columns.Add("a.name", typeof(string));
            dt2.Columns.Add("b.name", typeof(string));
            dt2.Rows.Add(new object[] { 1, "Hi" });
            dt2.Rows.Add(new object[] { 2, "Hi" });
            dt2.Rows.Add(new object[] { 3, "Hi" });
            dt2.Rows.Add(new object[] { 4, "Hi" });
            dt2.Rows.Add(new object[] { 5, "Hi" });
            dt2.Rows.Add(new object[] { 6, "Hi" });
            dt2.Rows.Add(new object[] { 7, "Hi" });
            r1.DataContext = dt1;
            r2.DataContext = dt2;
        }
    }
}

Я скажу тебе, что происходит. Верхняя сетка данных заполнена заголовками столбцов и данными. Нижняя сетка данных имеет заголовки столбцов , но все строки пусты.

Ответы [ 4 ]

17 голосов
/ 21 марта 2013

Вы можете оставить AutoGenerateColumns равным true и добавить обработчик событий для обработки любых периодов (или других специальных символов):

    <DataGrid
    Name="r2"
          ItemsSource="{Binding Path=.}"
          AutoGeneratingColumn="r2_AutoGeneratingColumn">
    </DataGrid>

Codebehind:

private void r2_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    if (e.PropertyName.Contains('.') && e.Column is DataGridBoundColumn)
    {
        DataGridBoundColumn dataGridBoundColumn = e.Column as DataGridBoundColumn;
        dataGridBoundColumn.Binding = new Binding("[" + e.PropertyName + "]");
    }
}

Это сработало лучше для меня в сценарии MVVM.

16 голосов
/ 25 января 2011

Символ полной остановки в именах столбцов второй таблицы неправильно интерпретируется синтаксическим анализатором пути привязки. Посмотрите выходные данные отладки во время работы этого примера, и вы увидите, что автоматически сгенерированные столбцы были связаны с «a» и «b», а не с «a.name» и «b.name»

System.Windows.Data Error: 40 : BindingExpression path error: 'a' property not found on 'object' ''DataRowView' ... etc.
System.Windows.Data Error: 40 : BindingExpression path error: 'b' property not found on 'object' ''DataRowView' ... etc.

Существует несколько различных символов, которые имеют особое значение в пути привязки, включая точку ('.'), Косую черту ('/'), квадратные скобки ('[', ']') и скобки ('( ',') '), скобки приведут к сбою приложения. Эти специальные символы можно экранировать, окружив путь привязки квадратными скобками. Дополнительную информацию о путях и экранировании символов можно найти в Обзор объявлений привязки

Чтобы это исправить, вам нужно установить AutoGenerateColumns = "False" и указать привязки столбцов в xaml:

    <DataGrid
    x:Name="r2"
          ItemsSource="{Binding .}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="a.name" Binding="{Binding Path=[a.name]}" />
            <DataGridTextColumn Header="b.name" Binding="{Binding Path=[b.name]}" />
        </DataGrid.Columns>
    </DataGrid>

или программно в коде

        r2.AutoGenerateColumns = false;
        foreach( DataColumn column in dt2.Columns )
        {
            var gridColumn = new DataGridTextColumn()
            {
                Header = column.ColumnName,
                Binding = new Binding( "[" + column.ColumnName + "]" )
            };

            r2.Columns.Add( gridColumn );
        }

        r2.DataContext = dt2;
3 голосов
/ 31 мая 2010

Символ FULL STOP (точка / точка) не работает.
Даже экранирование с x \ 002E не сработало.

Вот компромисс с использованием символа MIDDLE DOT:

dt1.Columns.Add("a\x00B7name", typeof(string));  
dt1.Columns.Add("b\x00B7name", typeof(string));
1 голос
/ 17 апреля 2017

В итоге я заменил ONE DOT LEADER, и он отлично работал. Я импортировал свои данные из файла XML, и вместо использования string.replace(".","\x2024"); везде в моем коде было проще изменить файл импорта.

Before
<Components Description="Thru Tee" Size="0.5" Kv="0.54" />
After
<Components Description="Thru Tee" Size="0&#x2024;5" Kv="0.54" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...