- •Краткий путеводитель
- •Проектируйте
- •Сохраняйте гибкость
- •Коллекции элементов
- •Отрисовка
- •Придерживайтесь стандартов
- •Оптимизируйте
- •Взаимодействие с мышью
- •Взаимодействие с клавиатурой
- •Поведение в режиме дизайна
- •Использование атрибутов
- •Коллекции
- •Конверторы типов
- •Расширение компонентов
- •Локализация
- •Источники данных
- •Доступность
- •Конвертор типа
Локализация
В современном мире трудно предполагать, кто окажется пользователем вашего контрола, если, конечно, вы не делаете его для себя и не собираетесь использовать в одном-единственном приложении для каталога фотографий вашей любимой собачки. В коммерческих компонентах и контролах необходимо предусмотреть возможность их использования в приложениях, написанных для разных языков, культур и стран. Для этого нужно обеспечить возможность локализации вашего контрола.
Локализация – это не только перевод текста. В зависимости от целевой аудитории конечного продукта изменениям могут подвергнуться и расположение контролов на форме, и выравнивание текста, и даже цвета. Также необходимо помнить, что вы сами можете поставлять различные версии вашей библиотеки контролов для разных стран, языков и культур, в которых отличаются описания свойств, категории, а также описание ошибок в генерируемых исключениях.
Значения свойств в локализованных формах не сериализуются в код, а сохраняются в отдельных ресурсах для каждой использованной культуры. Поэтому типы свойств должны быть сериализуемы, иначе дизайнер не сможет сохранить их.
Используйте атрибут Localizable с параметром true, чтобы указать, что данное свойство является локализуемым. Свойства, не предназначенные для пользователя, и не влияющие на отображение и расположение контрола, помечайте атрибутом [Localizable(false)], чтобы уменьшить объем ресурсов. Например, свойство object Tag { get; set; } обычно является нелокализуемым.
Помните о том, что существуют языки, в которых нормальным направлением текста является справа налево, например, Арабский или Иврит. Для этого существует свойство RightToLeft. Если в вашем контроле существует определенная ориентация представления информации, вам понадобится учитывать это свойство. Например, выравнивание текста по умолчанию производится к правой границе, полосы прокрутки расположены слева от контрола, информация о прогрессе (ProgressBar) отображаются справа налево и так далее.
Если в вашем контроле используется какой-либо вид выравнивания, используйте ContentAlignment для физического выравнивания, независимого от свойства RightToLeft. Используйте StringAlignment, если необходимо выравнивать строки и учитывать RightToLeft. При этом значение Near означает слева для RightToLeft.No и справа для RightToLeft.Yes, значение Far, соответственно, наоборот.
Источники данных
Связь контролов со структурами данных, такими, как DataTable, коллекциями или просто объектами сокращает количество кода и упрощает разработку. В Windows Forms за это отвечает механизм Data Binding. К сожалению, Data Binding имеет, пожалуй, самую неудачную реализацию из всей библиотеки .NET Framework. По этой причине многие авторы библиотек компонентов реализуют свою собственную стратегию связи с данными. Если же вы решитесь-таки использовать Data Binding, при создании контролов вам понадобится следовать нескольким простым правилам.
Привязка к данным может быть двух видов – к записи или списку. Некоторые контролы, вроде ListBox привязываются к источнику данных (DataSource) и отображают все его элементы тем или иным способом. Другие, вроде TextBox, могут быть привязаны к некоторой колонке текущей записи в источнике данных, и при смене позиции их содержимое обновляется. Источником также может служить обычная коллекция, не имеющая отношения к базам данных.
Свойства, которые могут быть связаны с данными, помечайте атрибутом [Bindable(true)]. В этом случае они появятся в выпадающем списке (DataBindings), и к ним можно будет привязать источник. Очевидно, что такие свойства должны быть доступны как на чтение, так и на запись. Если атрибут Bindable не использован или использован со значением false, то к свойству всё равно можно подсоединить источник данных, хотя и без гарантий, что всё будет работать как нужно. Для этого надо открыть пункт Advanced в списке (DataBindings).
Предоставляйте событие <PropertyName>Changed, где PropertyName – имя свойства. Пользуясь этим событием, среда разработки и другие компоненты смогут узнать об изменении свойства и обновить информацию в связанных данных. Система связи с данными также подписывается на событие Validating, если оно есть. При этом происходит попытка передать данные в источник данных для обновления, а при ошибке выставляется флаг Cancel в CancelEventArgs.
Если вы предоставите свойство <PropertyName>IsNull типа bool, то в случае true значением свойства будет считаться DbNull, а само свойство опрашиваться не будет.
Если вы разрабатываете контрол, который должен привязываться ко всему источнику данных, используйте CurrencyManager в качестве менеджера связи. Название этого класса неудачно, но именно этот наследник BindingManagerBase используется в контролах Windows Forms для управления связью со списками. Для связи с одним объектом используется другой класс – PropertyManager.
