Настройка DataGrid
59WPF --- Элементы управления WPF --- Настройка DataGrid
Закрепление столбцов
Закрепляемый столбец остается на месте в левой части элемента управления DataGrid, даже при прокручивании содержимого вправо. На рисунке показано, что закрепленный столбец Product остается видимым во время прокручивания. Обратите внимание, что горизонтальная полоса прокрутки находится только под прокручиваемыми столбцами, но не под закрепленным:
Возможность закреплять (freezing) столбцы полезна, когда нужно, чтобы определенная информация (наподобие имени товара или уникального идентификатора) всегда оставалось видимой. Она включается установкой в свойстве DataGrid.FrozenColumnCount значения больше нуля. Например, установка в 1 приводит к закреплению первого столбца:
<DataGrid x:Name="gridProducts" Margin="5" AutoGenerateColumns="False" RowHeight="100" LoadingRow="gridProducts_LoadingRow"
FrozenColumnCount="1">
Закрепленные столбцы должны всегда размещаться в левой части сетки. Если закрепляется один столбец, это будет столбец, являющийся крайним слева, в случае закрепления двух столбцов это будут два первых столбца слева и т.д.
Выбор
Как и в обычном списковом элементе управления, в DataGrid пользователь имеет возможность выбирать отдельные элементы. Когда это происходит, инициируется событие SelectionChanged, на которое можно отреагировать. Для выяснения того, какой объект данных является выбранным в текущий момент, можно использовать свойство SelectedItem. Если установить для свойства SelectionMode значение Extended, пользователь сможет выбирать сразу несколько строк. (Еще одним доступным вариантом является значение Single, которое применяется для этого свойства по умолчанию.) Выбор множества строк осуществляется при нажатой клавише <Shift> или <Ctrl>. Коллекция выбранных элементов хранится в свойстве SelectedItems.
Установка выбора в коде производится с использованием свойства SelectedItem. Если это делается для элемента, который в текущий момент не находится в поле зрения, разумно сопровождать это вызовом метода DataGrid.ScrollIntoView(). Тогда DataGrid выполнит прокрутку вперед или назад, пока указанный элемент не станет видимым.
Сортировка
Элемент управления DataGrid имеет встроенную функцию сортировки, для использования которой требуется привязка к коллекции, реализующей интерфейс IList (такой как List<T> или ObservableCollection<T>). В этом случае элемент управления DataGrid автоматически получает базовые возможности сортировки.
Для применения сортировки пользователь должен щелкать на заголовке столбца. Одиночный щелчок сортирует элементы столбца по возрастанию на основе типа данных (например, числа сортируются от 0 и дальше по мере увеличения, а буквы — в алфавитном порядке). Повторный щелчок приводит к сортировке в обратном порядке. Справа от заголовка столбца появляется стрелка, которая показывает, что в DataGrid произведена сортировка на основе значений в данном столбце. Стрелка, указывающая вверх, обозначает сортировку по возрастанию, а вниз — по убыванию.
Пользователи могут выполнять сортировку сразу в нескольких столбцах, удерживая нажатой клавишу <Shift> во время щелчка. Например, удерживая нажатой клавишу <Shift> и щелкая на столбце Category, а затем на столбце Price, можно отсортировать товары по группам категорий в алфавитном порядке и упорядочить элементы внутри каждой группы по цене.
Обычно в алгоритме сортировки DataGrid используются привязанные данные, которые отображаются в столбце, в чем есть смысл. Тем не менее, можно выбирать и другое свойство из привязанного объекта данных, устанавливая свойство SortMemberPath столбца. Для DataGridTemplateColumn использование этого свойства вообще обязательно, поскольку в этом классе нет свойства Binding для предоставления привязанных данных. В противном случае функция сортировки в столбце поддерживаться не будет.
Для отключения функции сортировки во всей сетке необходимо установить свойство CanUserSortColumns в false. Для отключения ее в отдельном столбце понадобится установить в false свойство CanUserSort этого столбца.
Редактирование в DataGrid
Одним из главных удобств в элементе управления DataGrid является предлагаемая в нем поддержка редактирования. Каждая ячейка в DataGrid переключается в режим редактирования, когда пользователь выполняет на ней двойной щелчок. Ограничивать эту возможность DataGrid можно несколькими способами.
DataGrid.IsReadOnly. Если это свойство равно true, пользователи не могут выполнять редактирование.
DataGridColumn.IsReadOnly. Если это свойство равно true, пользователи не могут выполнять редактирование значений в данном столбце.
Свойства, предназначенные только для чтения. Если объект данных имеет свойство без средства установки (Setter), элемент управления DataGrid распознает это и отключает возможность редактирования в соответствующем столбце (как если бы свойство DataGridColumn.IsReadOnly было установлено в true). Аналогично, если свойство не является простым текстом, числом или датой, элемент управления DataGrid делает его доступным только для чтения (хотя эту ситуацию можно обойти за счет использования DataGridTemplateColumn).
То, что происходит при переводе ячейки в режим редактирования, зависит от типа столбца. В столбце DataGridTextColumn отображается текстовое поле (которое выглядит не очень гладко, заполняет собой всю ячейку и не имеет видимой границы). В столбце DataGridCheckBox отображается флажок, который можно отмечать и снимать отметку. Но самым интересным является столбец DataGridTemplateColumn. В нем можно заменить стандартное текстовое поле для редактирования более специализированным элементом управления вводом.
Например, в показанном ниже столбце отображается дата. Двойной щелчок на нем приводит к появлению раскрывающегося элемента управления DatePicker, в котором уже выбрано текущее значение:
В DataGrid автоматически поддерживается базовая система проверки достоверности, которая реагирует на проблемы в системе привязки данных (вроде невозможности преобразования предоставляемого текста в нужный тип данных) либо исключения, выдаваемые средством установки свойства.
Шаблон ErrorTemplate, применяемый для DataGridCell по умолчанию, предусматривает отображение рамки красного цвета вокруг недействительного значения, что очень похоже на поведение других элементов управления вводом, таких как TextBox.
Проверка достоверности может быть реализована в DataGrid и другими способами. Один из них предусматривает использование событий DataGrid, связанных с редактированием, которые описаны ниже. События перечислены в порядке их возникновения в DataGrid:
- BeginningEdit
Возникает перед переводом ячейки в режим редактирования. В этот момент можно просмотреть столбец и строку, которые будут редактироваться, проверить значение ячейки и отменить эту операцию с использованием свойства DataGridBeginningEditEventArgs.Cancel
- PreparingCellForEdit
Применяется для шаблонных столбцов. В этот момент можно выполнить любую инициализацию, которая требуется для элементов управления редактированием. Для доступа к элементу в CellEditingTemplate используется свойство DataGridPreparingCellForEditEventArgs.EditingElement
- CellEditEnding
Возникает перед выходом ячейки из режима редактирования, DataGridCellEditEndingEventArgs.EditAction позволяет узнать, пытается пользователь применить редактирование (например, нажимая клавишу <Enter> или щелкая на другой ячейке) или отменить его (нажатием клавиши <Escape>). В этот момент можно просмотреть новые данные и установить свойство Cancel для отката изменений
- RowEditEnding
Возникает при переходе пользователем на новую строку после редактирования текущей. Как и в случае CellEditEnding, в этот момент можно выполнить проверку достоверности и отменить изменения. Обычно проверка достоверности охватывает несколько столбцов, например, когда значение в одном столбце не должно быть больше значения в другом столбце
Когда необходима логика проверки достоверности, специфичная для страницы (и потому включать ее в объекты данных нельзя), можно поместить ее в обработчики событий CellEditEnding и RowEditEnding. В обработчике CellEditEnding выполняется проверка правил, связанных со столбцом, а согласованность целой строки проверяется в обработчике событий RowEditEnding. Помните, что в случае отмены редактирования понадобится предоставить описание проблемы (обычно в элементе TextBlock где-то на странице).