Поведение в режиме дизайна
Не полагайтесь на порядок установки значений свойств контрола дизайнером и тем более не подразумевайте, что некоторое свойство будет уже выставлено к моменту выставления другого свойства. Если избежать этого невозможно в силу особых свойств контрола, используйте интерфейс ISupportInitialize. Если некоторый компонент реализует этот интерфейс, дизайнер вставит вызов BeginInit перед началом инициализации и EndInit по окончании. Таким образом, вы сможете отследить, что инициализация закончена и, например, вызвать Recalculate для расчёта необходимых данных.
Во многих случаях необходимо знать, используется ваш контрол в данный момент в нормальных условиях (в работающем приложении) или же в режиме дизайна. Для этого необходимо использовать свойство DesignMode у сайта контрола (объекта, реализующего ISite). Если контрол уже сконструирован и находится в своём контейнере (например, форме), то его сайт можно получить, используя свойство Site – оно есть у любого компонента и контрола.
Если же вам необходимо узнать это еще в конструкторе, то всё становится несколько сложнее. Для начала попробуйте перепроектировать контрол таким образом, чтобы определение режима не требовалось в конструкторе или методе, вызываемом из него.
Если это невозможно по каким-либо причинам, придётся использовать медленный способ трассировки стека вызовов. В данном примере реализации такой проверки мы сначала пытаемся использовать быстрый способ. Если это не удалось, то мы просматриваем стек вызовов в поисках объекта, реализующего IDesignerHost. При нахождении такового мы делаем вывод, что мы находимся в дизайн-тайме. В реальном приложении может иметь смысл ограничить глубину просмотра стека.
private bool IsDesignMode() { if(Site != null ) return Site.DesignMode;
StackTrace stackTrace = new StackTrace(); int frameCount = stackTrace.FrameCount - 1;
for( int frame = 0; frame < frameCount; frame++ ) { Type type = stackTrace.GetFrame(frame).GetMethod().DeclaringType; if (typeof(IDesignerHost).IsAssignableFrom(type)) return true; } return false; }
|
Также можно проверить, что исполняемой design-средой является Visual Studio: if (Application.ExecutablePath.ToLower().IndexOf("devenv.exe") > -1). Этот способ, хотя и быстрее, не позволит вам правильно определить другие возможные дизайнеры, например SharpDevelop.
- Краткий путеводитель
- Проектируйте
- Сохраняйте гибкость
- Коллекции элементов
- Отрисовка
- Придерживайтесь стандартов
- Оптимизируйте
- Взаимодействие с мышью
- Взаимодействие с клавиатурой
- Поведение в режиме дизайна
- Использование атрибутов
- Коллекции
- Конверторы типов
- Расширение компонентов
- Локализация
- Источники данных
- Доступность
- Конвертор типа