Форматирование строк DataGrid
81WPF --- Элементы управления WPF --- Форматирование строк DataGrid
Устанавливая свойства объектов столбцов DataGrid, можно управлять форматированием целых столбцов. Во многих случаях полезно помечать строки со специфическими данными. Например, может понадобиться привлечь внимание к товарам с высокой ценой или доставкам с истекшим сроком исполнения. Подобного рода форматирование можно реализовать программно, обрабатывая событие DataGrid.LoadingRow.
Событие LoadingRow является очень мощным инструментом для форматирования строк. Оно предоставляет доступ к объекту данных текущей строки, позволяя выполнять простые проверки диапазонов, сравнения и более сложные операции. Оно также предоставляет доступ к объекту DataGridRow строки, что дает возможность форматировать строку и применять к ней другие цвета или другой шрифт Однако форматировать какую-то одну ячейку в этой строке не удастся — для этого нужно использовать DataGridTemplateColumn и специальный конвертер значений.
Событие LoadingRow генерируется один раз для каждой строки при ее появлении на экране. Преимущество такого подхода состоит в том, что приложение никогда не должно форматировать всю сетку: вместо этого событие LoadingRow срабатывает только для тех строк, которые видимы в текущий момент. Но есть также и недостаток. При прокручивании пользователем сетки событие LoadingRow срабатывает постоянно. Поэтому помещать в метод LoadingRow код, требующий значительного времени на выполнение, нельзя, иначе операция прокручивания в приложении будет постепенно замедляться вплоть до полного останова.
Также существует один момент, который должен быть обязательно продуман — повторное использование контейнера элементов. Для снижения использования ресурсов памяти DataGrid предусматривает повторное применение тех же самых объектов DataGridRow для отображения новых данных при прокручивании сетки. (Именно поэтому событие называется LoadingRow, а не CreatingRow.) Если не соблюдать осторожность, DataGrid может загрузить данные в уже сформатированный объект DataGridRow. Для предотвращения такой ситуации нужно явно возвращать каждую строку в первоначальное состояние.
В следующем примере элементам с высокой ценой придается ярко-оранжевый фон, а элементам с обычной ценой — стандартный белый фон:
private SolidColorBrush hb = new SolidColorBrush(Colors.Orange);
private SolidColorBrush nb = new SolidColorBrush(Colors.White);
private void gridProducts_LoadingRow(object sender, DataGridRowEventArgs e)
{
Product product = (Product)e.Row.DataContext;
if (product.UnitCost > 100)
e.Row.Background = hb;
else
e.Row.Background = nb;
}
Следует иметь в виду, что доступен еще один вариант для форматирования на основе значений — использование конвертера значений, который анализирует привязанные данные и преобразует их в что-то другое. Этот прием особенно мощный, когда применяется в сочетании с DataGridTemplateColumn.
Например, можно создать шаблонный столбец, содержащий элемент TextBlock, и привязать его свойство TextBlock.Background к конвертеру значений, который устанавливает цвет на основе цены. В отличие от продемонстрированного выше приема с применением события LoadingRow, такой подход позволяет применять форматирование только к ячейке, в которой содержится цена, а не ко всей строке.
Форматирование, определяемое в обработчике событий LoadingRow, будет применяться только при загрузке строки. В случае редактирования строки этот код LoadingRow срабатывать не будет (по крайней мере, до тех пор, пока строка не исчезнет из поля зрения за счет прокручивания, а потом вернется обратно).
Детали строк
В DataGrid поддерживаются так называемые детали строк (row details) — отдельная дополнительная область, которая появляется непосредственно под значениями столбца для строки. Эта область предоставляет две дополнительных возможности, которые недоступны при наличии одних только столбцов:
Она занимает всю ширину DataGrid и не врезается в отдельные столбцы, обеспечивая больше пространства для работы.
Ее можно сконфигурировать так, чтобы она появлялась только для избранных строк, что позволяет убирать лишние детали, когда в них нет необходимости.
Ниже показан элемент управления DataGrid, в котором используются оба поведения. В области деталей строк отображается текст описания товара, причем только для товара, выделенного в текущий момент:
Для создания этого примера необходимо сначала определить содержимое, которое должно отображаться в области деталей строк, установив свойство RowDetailsTemplate. В данном случае для этой области используется базовый шаблон, который включает элемент TextBlock, отображающий полное описание товара, и границу вокруг него:
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Border Margin="10" Padding="10" BorderBrush="SteelBlue"
BorderThickness="2" CornerRadius="5">
<TextBlock Text="{Binding Path=Description}" TextWrapping="Wrap"
FontSize="10" MaxWidth="350"></TextBlock>
</Border>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
Можно также добавить элементы управления, которые позволяют выполнять различные задачи (например, извлечь дополнительную информацию о товаре, поместить товар в корзину для покупок, отредактировать сведения и т.д.).
Конфигурирование поведения, касающегося отображения области деталей строк, осуществляется установкой свойства DataGrid.RowDetailsVisibilityMode. По умолчанию для этого свойства устанавливается значение VisibleWhenSelected, указывающее, что область деталей должна отображаться при выборе строки. Значение Visible указывает, что область деталей каждой строки должна отображаться сразу же. Значение Collapsed определяет, что область деталей не должна отображаться ни для одной строки — по крайней мере, до тех пор, пока значение RowDetailsVisibilityMode не будет изменено в коде (например, при выборе пользователем определенного типа строки).