Проектируйте
Прежде чем создавать новый контрол или модифицировать поведение существующего, тщательно проанализируйте и осознайте, что именно вы хотите получить в результате. Нарисуйте предполагаемый результат ваших трудов на листке бумаги, в нескольких состояниях, определите важные участки контрола, составьте список прямоугольников, активных зон и частей. Опишите, какие области необходимо отрисовывать и каким образом, какие при этом используются цвета, стили и прочие настройки внешнего вида контрола. Не увлекайтесь особенно деталями, очертите только главные свойства и аспекты поведения контрола.
Спроектируйте структуру классов, которые будут использоваться для реализации контрола. Опишите специальные стили в виде перечислений (enum). Подготовьте список основных событий, о которых стоит оповещать пользователей вашего контрола. Создайте соответствующие делегаты и классы данных для них. Помните, что Windows Forms содержит довольно много классов, которые можно использовать повторно.
Составьте список основных вариантов использования (use cases) нового компонента или контрола. Опишите, как он будет реагировать на действия пользователя, какие состояния возможны и каковы переходы между ними. Это не только поможет не забыть реализовать то или иное поведение, но и будет хорошим подспорьем при тестировании функциональности – достаточно будет просто пробежаться по списку.
Зафиксируйте информацию о том, что является согласованным состоянием объекта. В процессе работы компонент будет подвергаться самым различным воздействиям и, возможно, совсем не тем образом, на который вы рассчитывали. Поэтому очень важно отслеживать согласованность состояния объекта, и при изменении некоторых внутренних данных соответственным образом менять и связанные. Например, в контроле вроде ListBox все выделенные (selected) элементы должны также находиться в коллекции всех имеющихся элементов, поэтому при удалении элемента из контрола необходимо также проверить, не является ли он выделенным, и удалить его из коллекции выбранных тоже.
Согласованность состояния особенно важна, если ваш компонент может работать в нескольких режимах, в зависимости от действий пользователя. Например, многоколоночный контрол может находиться в режиме изменения размеров колонок, и в этом случае отпускание кнопки мыши вне заголовка колонки не должно приводить к изменению текущего элемента или производить иное действие, которое в другом режиме производится по MouseUp. Тщательно опишите все возможные состояния объекта, поведение его в каждом из них и переходы из одного в другое. Впоследствии, если понадобится добавить еще один режим, не поленитесь и обновите документ - определите, как влияет новый режим на поведение старых, и внесите соответствующие изменения.
Для проверки соблюдения согласованности состояния вы можете создать метод VerifyConsistency(). Вызовы метода можно расставить везде, где изменяется внутреннее состояние компонента. Метод может проверить состояние объекта на согласованность и либо просто вернуть управление, либо сгенерировать исключение с описанием проблемы согласованности. Если снабдить этот метод атрибутом [Conditional(“DEBUG”)], то он будет вызываться только в debug-режиме, а в release-режиме компилятор не сгенерирует его вызов. Таким образом, вы не потеряете производительности при реальном использовании, а в случае проблемы при отладке получите её описание. Вы также можете создать собственную константу условной компиляции (например, “VERIFY”) и использовать её. Для этого откройте свойства проекта (Configuration Properties, Build) и в строке Conditional Compilation Constants добавьте свою константу.
- Краткий путеводитель
- Проектируйте
- Сохраняйте гибкость
- Коллекции элементов
- Отрисовка
- Придерживайтесь стандартов
- Оптимизируйте
- Взаимодействие с мышью
- Взаимодействие с клавиатурой
- Поведение в режиме дизайна
- Использование атрибутов
- Коллекции
- Конверторы типов
- Расширение компонентов
- Локализация
- Источники данных
- Доступность
- Конвертор типа