Залепа №10 Cупер-хренорезка может все. Только хрен не режет.
Еще раз перечитав эту статью, а именно пару абзацев про грамотное поведение окон, возникла идея применить это на практике. Как раз есть форма, до отказа набитая всякими элементами управления (далее - контролами), в числе которых имеются и такие, из которых могут выпадать вспомогательные окошки. А именно: ComboBox (в режиме DropDownList) и DateTimePicker. Из первого выпадает список возможных вариантов, из второго - более-менее симпатичный календарик.
Идея проста как две копейки - как только фокус попадает в какой-нить из этих контролов, он (контрол) тут же разворачивается во всей своей красе. Это спасает пользователя от лишнего судорожного хватания мыши и тыканья ею же в вышеупомянутый контрол.
Сразу скажу, что с ComboBox'ом особых проблем не возникло. Правда вызвало некоторое удивление то, что сворачивание/разворачивание списка осуществляется не методом, а свойством, что несколько противоречит здравому смыслу. Все таки сворачивание/разворачивание - это действие, а не характеристика.
Но потом, немного поразмыслив, я пришел к выводу, что это сделано видимо с целью дать программисту возможность отслеживать текущее состояние "свернутости" контрола. По крайней мере это более-менее логичное объяснение такому странному проектированию класса контрола. Хотя даже я, со своим извращенным мышлением, не могу придумать, в каком случае это отслеживание может реально понадобиться.
Ладно, нашел я комбо-боксовое свойство DroppedDown и быстренько соорудил метод:
private void Combo_Enter(object sender, EventArgs e)
{
ComboBox cb = (ComboBox)sender;
cb.DroppedDown = true;
}и подцепил на него события OnEnter от всех комбо-боксов.
Естественно все скомпилировалось, запустилось и даже заработало. :) Возник соблазн подцепить до кучи еще и дате-тайм-пикеры. Снова полез в MSDN, посмотреть, как же будет зваться свойство, разворачивающее календарь, ибо, наученный горьким опытом копания в коде майкрософта, я твердо знаю, что метод, выполняющий одни и те же действия в разных (пусть даже схожих) контролах будет зваться по-разному. И, как показывает практика, может оказаться вовсе и не методом, а например свойством или даже событием... :)
Чем глубже я закапывался в изучение списка методов и свойств класса DateTimePicker, тем больше мне казалось, что его проектировали не совсем вменяемые люди. Вот только некоторые ляпы:
Метод DrawToBitmap, позволяющий (наверное) нарисовать наш элемент управления в заранее созданный битмап. Интересно, нарисует только строчку с датой или еще и развернутый календарь??? Кому и зачем это может понадобиться - для меня загадка.
GetAutoSizeMode возвращает одно из значений перечисления AutoSizeMode, которое содержит всего два таких значения: GrowAndShrink и GrowOnly.
Нафига это надо, если у контрола есть свойство AutoSize. Поменяйте его тип с bool на int и к списку свойств GrowAndShrink и GrowOnly добавьте еще и None, и можно "облегчить" класс на целый метод.
Чуть ниже нашел то, о чем уже писал в предыдущих постах: This property supports the .NET Framework infrastructure and is not intended to be used directly from your code. О как! Оказывается свойство есть, но пользоваться им низзя! Спрашивается, зачем оно тогда есть? Аа-а-а, да! Это будет наверное реализовано в будущих версиях... Или уже было реализовано в прошлых... Все равно маразм! :(
Свойства CompanyName, ProductName и ProductVersion существуют вообще везде, где только можно. Понятно, нужно знать кто и когда соорудил тот или иной класс, особенно если это коммерческая разработка. Но вот только не ясно, какое именно отношение эти свойства имеют к календарю, ровно как и к любому другому контролу.
Controls - коллекция внедренных контролов. Никогда бы не подумал, что человеку в здравом уме придет в голову использовать строчку ввода даты как площадку для размещения дополнительных элементов управления. Видимо я старею, не поспеваю за прогрессом, отстаю от жизни, а все нормальные кодеры уже давно пихают туда таблицы, прогресс-бары и кнопки всех мастей. :)
Продолжение предыдущего пункта - метод GetNextControl, выдающий следующий из списка дочерних контролов. Ну коль уж так хочется напихать в календарь еще и прогресс-баров с радио-кнопками и полями ввода RTF-текста, то почему их нельзя перебрать просто как массив? Ах можно? Тогда нафига сделали этот метод? И почему в таком случае не сделали метод GetPrevControl, чтоб можно было перейти не только к следующему, но и к предыдущему????
Идем дальше. Свойство HasChildren возвращает логическое значение, точно определяющее, есть ли у нас дочерние контролы али нет таких. Видимо, по мнению майкрософта, пользователи их библиотек настолько тупы, что для них нужно было создать отдельное свойство, а просто сравнить с нулем количество элементов в массиве Controls они не догадаются. Жуть. :(
DropDownAlign - тоже очень полезная вещь. Вот только реальной практической пользы в нем я тоже не нахожу.
Отдельно стоит рассмотреть целую коллекцию свойств, которой обладают абсолютно все контролы. Это Height, Width и Size, а также их сородичи: Left, Top и Location. Причиной их появления стала все та же предусмотрительность дядек из Microsoft, которые (для нашего "удобства") тупо продублировали одни и те же свойства, обозвав их разными именами.
Сюда же стоит отнести и свойства Right и Bottom. Наверное рядовой программер не в состоянии запрограммировать операцию сложения двух целых чисел и ему для определения координат окна нужно ввести дополнительные свойства.
Region - а вдруг кому-нить захочется сделать календарик круглым или с дыркой. Нельзя отнимать у программиста-разработчика такую бесценную возможность!
MaximumSize и MinimumSize. Эти два свойства предназначены видимо для тех мега-программеров, которые осилили учебник языка C# только до раздела "События", а дальше - забили. Т.к. если разработчик знает, что такое события и как отследить изменение размеров окна, то для него потребность в этих свойствах никогда не возникнет.
Text и Value. Тоже братья-близнецы. Созданы специально для ленивых, которым влом написать a = dtp.Value.ToString(). Теперь у них есть более короткий (и естественно более понятный) вариант: a = dtp.Text.
FindForm и Parent. Еще один способ облегчить тяжелую жизнь программистам: циклы типа while(m.parent != null) m = m.parent; нынче не в моде. Нам надо отдельное свойство для решения таких сверх-сложных задач.
Ну и под конец два гениальных события: ContextMenuChanged и CursorChanged. Первое наступает, когда у контрола изменилось контекстное меню (гениально, правда???), второе - (держитесь за стул, ибо упадете) наступает, когда поменялся курсор.
Хоть убейте, но практического применения этим событиям я придумать не могу. Если у кого-нить из читателей этой статьи есть здравые мысли по этому поводу, пожалуйста выскажитесь в комментах. Буду очень признателен.
Вот такой вот цирк.
Но суть этой статьи сводится не к тому, что в библиотеке .NET Framework масса лишнего мусора, а к тому, что ни свойства, ни метода для программного разворачивания календаря я так и не обнаружил. Наверное про него гении из майкрософта просто забыли. Еще бы! Ведь надо было запрограммировать весь вышеописанный бред, а сроки сдачи коммерческого проекта .NET Framework 2.0 ведь не резиновые, вот и не успели...
http://fit-media.com/post_1202303173.html

Можно сделать все. То есть абсолютно все.
(13 марта 2008, 11:15)Следовательно, раз разработчики не предусмотрели какой-то возможности, то ее все же можно добавить. Но способ этот ни корректным, ни правильным назвать нельзя. Итак...
В обработчик события Enter (получение контролом фокуса ввода) добавляем команду: SendKeys.Send("{F4}"); и все получается.
Остается только гадать, неужели умельцы из мелкософта так сильно заняты, что им было некогда добавить эту функцию в свой контрол...