Всем привет!
Надеюсь, своей статьей я внесу ясность в вопросе связки 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;
}
}
}
Проверку на цифры можно сделать и через регулярные выражения.
Всем удачного релиза!