понедельник, 21 марта 2011 г.

WPF DataGrid и раскраска (выделение цветом) ячеек и строк (HOWTO)

Иногда возникает необходимость выделить цветом какие-нибудь данные в DataGrid’е. Давайте рассмотрим, как это можно сделать в WPF.
Для примера создадим класс Person
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

Пишем небольшую заполнялку тестовых данных:
private List<Person> GenerateSampleData()
{
    Random r = new Random();
    List<Person> personList = new List<Person>();
    for (int i = 1; i <= 100; i++)
    {
        personList.Add(new Person { Id = i, Name = String.Format("Person Name {0}", i), Age = r.Next(60) });
    }
    return personList;
}

Кидаем на поверхность окна DataGrid и в конструкторе формы заполняем данными:
this.dataGrid1.ItemsSource = GenerateSampleData();

И получаем вот такую милую/унылую таблицу.


Допустим, у нас стоит задача выделить цветом те “персоны”, возраст которых не достиг 16 лет.


1.1. В определение окна добавляем ссылку на пространство имен текущего проекта

xmlns:local="clr-namespace:DataGridColor"
 

1.2. Создаем конвертер, который будет преобразовывать возраст в кисть, которой будем закрашивать фон
 
class AgeToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Все проверки для краткости выкинул
        return (int)value <= 16 ? 
            new SolidColorBrush(Colors.OrangeRed)
            : new SolidColorBrush(Colors.White);
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new Exception("The method or operation is not implemented.");
    }
}


1.3. В ресурсах окна определяем ключ конвертера
<local:AgeToColorConverter x:key="AgeToColorConverter">

1.4. И там же, в ресурсах окна, объявляем стиль, TargetType у которого будет DataGridRow.

<Style TargetType="{x:Type DataGridRow}">
    <Setter Property="Background" Value="{Binding Age, Converter={StaticResource AgeToColorConverter}}" />
</Style>

В результате получаем вот такую полосатую таблицу:



А что если нужно выделять цветом не всю строку, а только отдельные ячейки в колонке. Для примера, нужно выделить ячейки с идентификатором меньше либо равно 16.

Эта задача решается похожим способом.

2.1. Добавляем в проект еще один конвертер
class IdToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Все проверки для краткости выкинул
        return (int)value <= 16 ?
            new SolidColorBrush(Colors.Yellow)
            : new SolidColorBrush(Colors.Green);
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new Exception("The method or operation is not implemented.");
    }
}

2.2 Присваивам ключ
<local:IdToColorConverter x:Key="IdToColorConverter" />

2.3. Добавляем в ресурсы окна еще один стиль, TargetType’ом у которого является  DataGridCell. Так же стилю присваиваем ключ посредством указания x:Key="IdStyle", иначе стиль будет применен для всех ячеек во всех таблицах (а ведь нам этого не нужно).
<Style x:Key="IdStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="{Binding Id, Converter={StaticResource IdToColorConverter}}" />
</Style> 


2.4. И для колонки, в которой хотим использовать раскраску отличную от всей строки указываем CellStyle:

<DataGridTextColumn Header="ID" Width="50" 
                    Binding="{Binding Id}" 
                    CellStyle="{StaticResource IdStyle}"/>


2.5. Если раздражает, что цвет Border’a ячейки теперь берется из цвета Background’а строки,  модифицируем стиль для ячейки устанавливая закраску Border’a белым цветом
<Style x:Key="IdStyle" TargetType="{x:Type DataGridCell}">
    <Setter Property="Background" Value="{Binding Id, Converter={StaticResource IdToColorConverter}}" />
    <Setter Property="BorderBrush"  Value="White" />
</Style>






Собственно, чтобы привлечь внимание к определенной ячейке не обязательно делать из DataGrid’а приведенного попугая, достаточно подкрашивать Border присваивая BorderBrush’у акцентирующую кисть.

Если есть вопросы – задавайте, будем разбираться вместе.

UPDATE: Если нужно раскрашивать строчки в зависимости от значений нескольких полей в таблице, то следует использовать MultiBinding и реализовывать интерфейс IMultiValueConverter. Для примера реализован вариант запрошенный io, когда нужно выделить строку, если идентификатор меньше 10 или возраст меньше 16.
Пример использования MultiBinding'а:
<Style TargetType="{x:Type DataGridRow}">
  <Setter Property="Background">
    <Setter.Value>
      <MultiBinding Converter="{StaticResource MultiBindingConverter}">
        <Binding Path="Id"/>
        <Binding Path="Age"/>
      </MultiBinding>
    </Setter.Value>
  </Setter>
</Style>

Пример реализации IMultiValueConverter'а:
    class MultiBindingConverter:IMultiValueConverter

    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ((int)values[0] <10 || (int)values[1]<16) ? 
                new SolidColorBrush(Colors.OrangeRed)
                : new SolidColorBrush(Colors.White);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

PS. Выложил исходники.

среда, 16 марта 2011 г.

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 5: Stabilizing and Releasing a Solution

>>В начало

Требования к знаниям:

  • Implement a WPF test strategy.
    This objective may include but is not limited to: automation peer, UI automation, IntelliTrace
  • Debug XAML by using the WPF Visualizer.
    This objective may include but is not limited to: accessing the Visualizer, drilling down into the visual tree, viewing and changing properties
    This objective does not include: setting a breakpoint and stepping through code
  • Debug WPF issues by using PresentationTraceSources.
    This objective may include but is not limited to: animation, data binding, dependency properties
  • Configure a ClickOnce deployment.
    This objective may include but is not limited to: configuring the installation of a WinForms, WPF, or XBAP application by using ClickOnce technology; choosing appropriate settings to manage upgrades
  • Create and configure a Windows Installer project.
    This objective may include but is not limited to: configuring a setup project to add icons during setup, setting deployment project properties, configuring conditional installation based on operating system versions, setting appropriate Launch Conditions based on the .NET Framework version, adding custom actions to a setup project, adding error-handling code to a setup project
  • Configure deployment security settings.
    This objective may include but is not limited to: configuring and integrating UAC by using ClickOnce deployments; setting appropriate security permissions to deploy the application

Ссылки на MSDN:

Статьи/Блоги:
Трассировка событий в приложении Windows Presentation Foundation
Поэтапное создание проекта установки и развертывания приложения WPF

MSDN Magazine/RU:
Поиск и устранение уязвимостей до выпуска приложения
Автоматизация тестирования пользовательского интерфейса в приложениях WPF

Video на TechDays/RU:
DependencyObject и DependencyProperty

Video на WindowsClient/EN:
Deploying a Standard WPF Application Using ClickOnce and Visual Studio
ClickOnce for Application Deployment

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 4: Enhancing the Functionality and Usability of a Solution

>>В начало

Требования к знаниям:

  • Integrate WinForms and WPF within an application.
    This objective may include but is not limited to: using ElementHosts within WinForms and ControlHosts within WPF; using the PropertyMap property
  • Implement asynchronous processes and threading.
    This objective may include but is not limited to: implementing asynchronous programming patterns; marshalling between threads; freezing UI elements; using timers; Task Parallel Library; parallel LINQ; using the dispatcher; BackgroundWorker component
  • Incorporate globalization and localization features.
    This objective may include but is not limited to: loading resources by locale; marking localizable elements; using culture settings in validators and converters; using language properties and rendering direction properties; working with resource files for localization; determining installed locales; regional settings
  • Implement drag and drop operations within and across applications.
    This objective does not include: Dynamic Data Exchange (DDE)
  • Implement security features of an application.
    This objective may include but is not limited to: configuring Software Restriction Policy (SRP); full trust and partially trusted security; interoperability with legacy CAS policy; User Account Control (UAC)
  • Manage user and application settings.
    This objective may include but is not limited to: creating application settings; creating user settings; loading and saving settings
    This objective does not include: persisting to database
  • Implement dependency properties.
    This objective may include but is not limited to: enabling data binding and animation, property metadata, property change callbacks

Ссылки на MSDN:

Статьи/Блоги:
Доступ к значениям App.Config в WPF

MSDN Magazine/RU:
Создание более быстро реагирующих приложений с Dispatcher
Свойства зависимости и уведомления

Video на WindowsClient/EN:
How Do I: WinForms WPF Integration
How Do I: Use a WPF Control in a Windows Form using ElementHost
How Do I: Use Resource Files for Localization both in XAML and Code
How Do I: Build an Asynchronous Progress Bar in WPF
How Do I: Localize Applications using the CultureInfo Class

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 3: Managing Data at the User Interface Layer

>>В начало

Требования к знаниям:

  • Implement data binding.
    This objective may include but is not limited to: binding options, static and dynamic resources, element bindings, setting the correct binding mode and update mode; binding to nullable values
    This objective does not include: binding to a specific data source
  • Implement value converters in WPF.
    This objective may include but is not limited to: implementing custom value converters, implementing multivalue converters
  • Implement data validation.
    This objective may include but is not limited to: handling validation and providing user feedback via the error provider (WinForms) or data templates (WPF), IDataErrorInfo, validation control, form validation and control validation
  • Implement and consume change notification interfaces.
    This objective may include but is not limited to: implementing INotifyPropertyChanged; using INotifyCollectionChanged (ObservableCollection)
  • Prepare collections of data for display.
    This objective may include but is not limited to: filtering, sorting, and grouping data; LINQ; CollectionView (WPF), BindingSource object (WinForms)
  • Bind to hierarchical data.
    This objective may include but is not limited to: TreeView; MenuControl
  • Implement data-bound controls.
    This objective may include but is not limited to: using the DataGridView (WinForms) or DataGrid (WPF) control to display and update the data contained in a data source, implementing complex data binding to integrate data from multiple sources; ItemsControl-derived controls (WPF)
  • Create a data template in WPF.
    This objective may include but is not limited to: implementing a data template selector; using templates with ItemsControl

Ссылки на MSDN:

Статьи/Блоги:
Интерфейс IValueConverter
Привязка данных к полю со списком WPF
DataGrid в WPF
Настраиваемый цвет сетки элемента управления Datagrid в WPF
Настраиваемая высота строки и заголовка элемента
управления Datagrid в WPF

Выравнивание ячеек в элементе управления DataGrid в WPF
Отображение иерархической структуры данных в WPF с помощью привязки и шаблонов
Шпаргалка по биндингу (PDF/EN)

MSDN Magazine/RU:
Настройка отображения данных с привязкой данных и WPF
Применение в WPF сложных бизнес-правил к вводу данных
Привязка данных в Windows Presentation Foundation
Класс ObservableCollection

 Video на TechDays/RU:
Создание приложений доступа к данным с помощью WPF
Лекция: Создание приложений доступа к данным с помощью Windows Presentation Foundation

Video на WindowsClient/EN:
How Do I: Use TargetNullValue to Handle Nullable Types in WPF Binding
How Do I: Use FallbackValue in WPF Binding
How Do I: Using StringFormat when Multibinding
How Do I: Change the Appearance of Grouped Data Using Styles
How Do I: Use CollectionViews to Sort and Filter Data
How Do I: Control Item Activation By Data Validation?
How Do I: Visually Indicate Binding Error Status
How Do I: Create a Custom Binding Validator
How Do I: Associate a Validation Rule with a Binding
Control How Data is Updated Using Binding Direction
Control When Bound Data is Updated
How Do I: Create and Use a Converter to Change DataTypes
How Do I: Build a ValueConverter to Format Bound Data in WPF
How Do I: Use the Observer Pattern

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 2: Enhancing a User Interface by Using Advanced Techniques

>>В начало

Требования к знаниям:

  • Manage routed events in WPF.
    This objective may include but is not limited to: tunneling vs. bubbling events, handling and cancelling events
    This objective does not include: simple event handling; creating custom events
  • Configure WPF commanding.
    This objective may include but is not limited to: defining WPF commands based on RoutedCommand; associating commands to controls; handling commands; command bindings; input gestures
    This objective does not include: creating custom commands by implementing ICommand
  • Modify the visual interface at run time.
    This objective may include but is not limited to: adding/removing controls at run time; manipulating the visual tree; control life cycle; generating a template dynamically
    This objective does not include: instantiating forms and simple modification of control properties at runtime
  • Implement user-defined controls.
    This objective may include but is not limited to: deciding whether to use a user/composite, extended, or custom control ; creating a user/composite control; extending from an existing control
    This objective does not include: creating a custom control by inheriting directly from the Control class and writing code
  • Create and display graphics.
    This objective may include but is not limited to: creating and displaying graphics by using geometric transformation; brushes; drawing shapes; clipping; double buffering; overriding Render (WPF) and OnPaint (WinForms); differentiating between retained and non-retained graphics
    This objective does not include: creating and displaying three-dimensional graphics; hit testing; creating images
  • Add multimedia content to an application in WPF.
    This objective may include but is not limited to: media player vs. media element; adding a sound player; images
    This objective does not include: buffering
  • Create and apply control templates in WPF.
    This objective may include but is not limited to: template binding
    This objective does not include: styling and theming; data templating
  • Create data, event, and property triggers in WPF.

Ссылки на MSDN:

Статьи/Блоги:
Общие сведения о перенаправленных событиях и командах в WPF
Команды в WPF. Часть I
Команды в WPF. Часть II
Команды в WPF. Часть III
Вводное руководство по WPF - Часть IV (Шаблоны данных и триггеры)
Добавление проигрывателя Windows Media в приложение WPF

MSDN Magazine/RU:
Знакомство с маршрутизированными событиями и командами в WPF
Векторная графика и класс Shape WPF
Добавление видео к элементам управления и трехмерным поверхностям с помощью WPF
Точечные рисунки и биты пикселов

Video на TechDays/RU:
Использование стилей и шаблонов при создании пользовательского интерфейса
Лекция: Элементы управления в Windows Presentation Foundation
Лекция: 2D и 3D графика в Windows Presentation Foundation

Video на WindowsClient/EN:
How Do I: Create a Custom Command in WPF
How Do I: Use Command Binding in WPF
Create User Controls in WPF
Implementing Property Triggers in WPF
Implementing Data Triggers in WPF
Complex Logic Using Triggers in WPF
Interactivity Through Triggers in WPF Control Templates

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 1: Building a User Interface by Using Basic Techniques

>>В начало

Требования к знаниям:

  • Choose the most appropriate control class.
    This objective may include but is not limited to: evaluating design requirements and then selecting the most appropriate control based on those requirements; recognizing when none of the standard controls meet requirements; item controls, menu controls, content controls
    This objective does not include: designing a custom control
  • Implement screen layout by using nested control hierarchies.
    This objective may include but is not limited to: using panel-derived controls, attaching properties
    This objective does not include: items controls, control customization
  • Create and apply styles and theming.
    This objective may include but is not limited to: application-level styles, overriding styles, style inheritance, Generic.xaml,  theming attributes
    This objective does not include: data-grid view style sharing
  • Manage reusable resources.
    This objective may include but is not limited to: fonts, styles, data sources, images, resource dictionaries, resource-only DLLs
  • Implement an animation in WPF.
    This objective may include but is not limited to: creating a storyboard; controlling timelines; controlling the behavior when the animation completes; double, color, and point animations; starting an animation from code and from XAML
    This objective does not include: direct rendering updates, implementing key frame animations

Ссылки на MSDN:

Статьи/Блоги:
Вводное руководство по WPF - Часть II (Layout)
Вводное руководство по WPF - Часть V (Стили)
Свойство зависимости в XAML
Работа с пропорциональными размерами в WPF
Стилизация приложений WPF
Windows Presentation Foundation : #013 Стилизация контролов WPF / Работа с ресурсами
Присоединенные свойства

 MSDN Magazine/RU:
Настройка элементов управления для Windows Presentation Foundation
Настройка элементов управления WPF при помощи шаблонов
Шаблоны для редко используемых элементов управления
Расширение классов анимации WPF

Video на TechDays/RU:
Лекция: Основы Windows Presentation Foundation
Основные принципы разработки приложений на WPF
Лекция: Шаблоны расположения элементов пользовательского интерфейса в Windows Presentation Foundation

Video на WindowsClient/EN:
WinForms-InheritingControls
How to Create a User Control in WPF
Windows Forms Layout
Layout Techniques for Windows Forms Developers
Grid Control Design-Time Row and Column Manipulation Features
Creating and Consuming Resource Dictionaries in WPF and Silverlight
How to Use Styles in WPF
How to Apply Control Templates in WPF
How to Use Data Templates in WPF
Sharing Styles Among Heterogeneous Elements
Override a Style for a Local Control’s Property Value in WPF
Style Inheritance using BasedOn in WPF
Apply Styles in WPF
Introduction to Themes in WPF
Basic Animation in WPF Using XAML
How Do I: Animate an Effect in WPF?
How Do I: Use Effects in WPF
Introduction to Easing Functions in WPF 4
How Do I: Custom Easing Functions in WPF 4

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 0.

За выступление в MCP клубе обещали премировать еще одним ваучером на бесплатную сдачу экзамена. Поэтому решил закрыть ветку Windows Application Development. Начнем с 511 экзамена.

Вводные данные:
Основная страница экзамена.
Требования к знаниям.

 Building a User Interface by Using Basic Techniques (23%)

  • Choose the most appropriate control class.
  • Implement screen layout by using nested control hierarchies.
  • Create and apply styles and theming.
  • Manage reusable resources.
  • Implement an animation in WPF.

Enhancing a User Interface by Using Advanced Techniques (21%)

  • Manage routed events in WPF.
  • Configure WPF commanding.
  • Modify the visual interface at run time.
  • Implement user-defined controls.
  • Create and display graphics.
  • Add multimedia content to an application in WPF.
  • Create and apply control templates in WPF.
  • Create data, event, and property triggers in WPF.

Managing Data at the User Interface Layer (23%)

  • Implement data binding.
  • Implement value converters in WPF.
  • Implement data validation.
  • Implement and consume change notification interfaces.
  • Prepare collections of data for display.
  • Bind to hierarchical data.
  • Implement data-bound controls.
  • Create a data template in WPF.

Enhancing the Functionality and Usability of a Solution (17%)

  • Integrate WinForms and WPF within an application.
  • Implement asynchronous processes and threading.
  • Incorporate globalization and localization features.
  • Implement drag and drop operations within and across applications.
  • Implement security features of an application.
  • Manage user and application settings.
  • Implement dependency properties.

Stabilizing and Releasing a Solution (17%)

  • Implement a WPF test strategy.
  • Debug XAML by using the WPF Visualizer.
  • Debug WPF issues by using PresentationTraceSources.
  • Configure a ClickOnce deployment.
  • Create and configure a Windows Installer project.
  • Configure deployment security settings.

Основные ссылки:
Раздел по WPF MSDN
Портал Windows Forms на MSDN
Доклады по WPF на TechDays
Центр Windows Presentation Foundation на MSDN
WPF Tutorial (неплохой сайт с большим количеством примеров/EN)

Учебники/книги:
MCTS Self-Paced Training Kit (Exam 70-511): Windows Application Development with Microsoft .NET Framework 4
WPF: Windows Presentation Foundation в .NET 4.0 с примерами на C# 2010 для профессионалов