Всем привет!
Надеюсь, своей статьей я внесу ясность в вопросе связки XML представления DataGrid с его кодовым собратом. Для этого лучше всего использовать конкретный пример. Итак, нам необходимо разместить список элементов некоторой структуры в таблице. Допустим сами элементы выглядят в коде следующим образом:
Соответственно, их список будет выглядеть как:
Теперь перейдем к DataGrid. Так как это все таки WPF, то вытянуть его на форму можно и руками. Пусть IDE сама отпишет для него код.
Здесь вручную я задал только AutoGenerateColumns=«False», так как в дальнейшем мы будем редактировать колонки таблицы сами.
Далее нам необходимо привязать данные к таблице, при этом каждое поле элемента должно соответствовать колонке таблицы.
Здесь использовано два вида колонок DataGridTextColumn и DataGridTemplateColumn. Про их виды можно почитать везде. Главное здесь понимать, что с помощью DataGridTemplateColumn можно задать любой шаблон. То есть, в ячейки этой колонки можно будет помещать любые элементы управления (кнопки, календари и т.д.). К примеру в третьей колонке это TextBox:
ВАЖНО: Не забывайте прописывать Header, потому что автозаполнение у нас отключено. А также для DataGridTemplateColumn необходимо прописать SortMemberPath, чтобы он знал по какому полю сортировать данные.
Перейдем к Binding. Это непосредственно сама привязка к данным. Ее мы указываем с помощью Binding Path=PhoneNumber. Здесь главное учесть то, что это именно название метода класса, который возвращает значение поля (не phoneNumber, а PhoneNumber, см. описание класса).
И еще один момент. Есть возможность ввести разные типы шаблонов (DataTemplate) для ячеек в обычном состоянии (CellTemplate) и в состоянии редактирования (CellEditingTemplate). В четвертой колонке ячейки в обычном состоянии это TextBox, а в состоянии редактирования DatePicker:
Также стоит отметить, что при работе с датами у поля Text есть свойство StringFormat, которое можно форматировать. Важно, что для корректного отображения месяца «ММ» должны быть большими.
Теперь, чтобы привязать конкретные данные к таблице вернемся к коду на C#.
После заполнения массива элементами, его надо указать в качестве источника данных:
Таким образом любые изменения в elements будут отображаться в таблице и, наоборот, любые сделанные изменения в таблице, приведут к изменениям в elements. Но при внесении изменений в elements необходимо вызывать метод
И в качестве еще одного хорошего примера связки С# — XML, приведу пример проверки заполнения ячеек телефонного номера только цифрами. Для этого немного подредактируем кусок кода третьей колонки:
Видно что в теге TextBox я назначил обработчик для события изменения текста. Теперь осталось только прописать этот обработчик в коде:
Проверку на цифры можно сделать и через регулярные выражения.
Всем удачного релиза!
Надеюсь, своей статьей я внесу ясность в вопросе связки XML представления DataGrid с его кодовым собратом. Для этого лучше всего использовать конкретный пример. Итак, нам необходимо разместить список элементов некоторой структуры в таблице. Допустим сами элементы выглядят в коде следующим образом:
class Element { public Element (string firstName, string lastName, string phoneNumber, DateTime date) { this.firstName = firstName; this.lastName = lastName; this.phoneNumber = phoneNumber; this.date = date; } public string FirstName { get { return this.firstName; } set { this.firstName = value; } } public string LastName { get { return this.lastName; } set { this.lastName = value; } } public string PhoneNumber { get { return this.phoneNumber; } set { this.phoneNumber = value; } } public DateTime Date { get { return this.date; } set { this.date = value; } } private string firstName; private string lastName; private string phoneNumber; private DateTime date; }
Соответственно, их список будет выглядеть как:
List<Element> elements = new List<Element>();
Теперь перейдем к DataGrid. Так как это все таки WPF, то вытянуть его на форму можно и руками. Пусть IDE сама отпишет для него код.
<DataGrid x:Name="dataGrid" Margin="10,103,0,15" CellEditEnding="dataGrid_CellEditEnding" Grid.RowSpan="2" Grid.ColumnSpan="2" HorizontalAlignment="Left" Width="728" AutoGenerateColumns="False"/>
Здесь вручную я задал только AutoGenerateColumns=«False», так как в дальнейшем мы будем редактировать колонки таблицы сами.
Далее нам необходимо привязать данные к таблице, при этом каждое поле элемента должно соответствовать колонке таблицы.
<DataGrid.Columns> <DataGridTextColumn Header="Имя" Binding="{Binding Path=FirstName}"/> <DataGridTextColumn Header="Фамилия" Binding="{Binding Path=LastName}"/> <DataGridTemplateColumn Header="Телефон" SortMemberPath="PhoneNumber"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}" /> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> <DataGridTemplateColumn Header="Дата" SortMemberPath="Date"> <DataGridTemplateColumn.CellTemplate> <DataTemplate > <TextBlock Text="{Binding Path=Date, StringFormat='dd/MM/yyyy'}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding Date}"/> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> </DataGrid.Columns>
Здесь использовано два вида колонок DataGridTextColumn и DataGridTemplateColumn. Про их виды можно почитать везде. Главное здесь понимать, что с помощью DataGridTemplateColumn можно задать любой шаблон. То есть, в ячейки этой колонки можно будет помещать любые элементы управления (кнопки, календари и т.д.). К примеру в третьей колонке это TextBox:
<DataGridTemplateColumn Header="Телефон" SortMemberPath="PhoneNumber"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate>
ВАЖНО: Не забывайте прописывать Header, потому что автозаполнение у нас отключено. А также для DataGridTemplateColumn необходимо прописать SortMemberPath, чтобы он знал по какому полю сортировать данные.
Перейдем к Binding. Это непосредственно сама привязка к данным. Ее мы указываем с помощью Binding Path=PhoneNumber. Здесь главное учесть то, что это именно название метода класса, который возвращает значение поля (не phoneNumber, а PhoneNumber, см. описание класса).
И еще один момент. Есть возможность ввести разные типы шаблонов (DataTemplate) для ячеек в обычном состоянии (CellTemplate) и в состоянии редактирования (CellEditingTemplate). В четвертой колонке ячейки в обычном состоянии это TextBox, а в состоянии редактирования DatePicker:
<DataGridTemplateColumn Header="Дата" SortMemberPath="Date"> <DataGridTemplateColumn.CellTemplate> <DataTemplate > <TextBlock Text="{Binding Path=Date, StringFormat='dd/MM/yyyy'}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding Date}"/> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn>
Также стоит отметить, что при работе с датами у поля Text есть свойство StringFormat, которое можно форматировать. Важно, что для корректного отображения месяца «ММ» должны быть большими.
Теперь, чтобы привязать конкретные данные к таблице вернемся к коду на C#.
После заполнения массива элементами, его надо указать в качестве источника данных:
dataGrid.ItemsSource = elements;
Таким образом любые изменения в elements будут отображаться в таблице и, наоборот, любые сделанные изменения в таблице, приведут к изменениям в elements. Но при внесении изменений в elements необходимо вызывать метод
.dataGrid.Items.Refresh();
И в качестве еще одного хорошего примера связки С# — XML, приведу пример проверки заполнения ячеек телефонного номера только цифрами. Для этого немного подредактируем кусок кода третьей колонки:
<DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding Path=PhoneNumber}" TextChanged="phN_TextChanged"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate>
Видно что в теге TextBox я назначил обработчик для события изменения текста. Теперь осталось только прописать этот обработчик в коде:
private void phN_TextChanged(object sender, TextChangedEventArgs e) { int result = 0; TextBox txtx = sender as TextBox; if (txtx !=null) { if (!int.TryParse(txtx.Text, out result)) { txtx.Text = txtx.Text.Substring(0, txtx.Text.Length - 1); txtx.CaretIndex = txtx.Text.Length; } } }
Проверку на цифры можно сделать и через регулярные выражения.
Всем удачного релиза!
