Залепа №7. Самые умные на свете.
Комплекс неполноценности майкрософта проявляется в самых разных формах. То они директоров школ на бабки разводят, то тортом в морду на глазах всего честного люда получают. Короче, используют всевозможные способы привлечь к себе внимание.
Ну и конечно же именно с ними должны все считаться, как с самыми авторитетными, самыми знающими и самыми прозорливыми. Вот об этом и поговорим. Точнее не о качествах конторы, а о качествах их продуктов, которое, как и качество всего остального, измеряется юзабельностью.
Итак, чем же мелкомягкие не угодили мне сегодня.
А сегодня я обнаружил, что оказывается, на многие действия пользователя софт-гигант уже предусмотрел свою, мудрую на их взгляд, реакцию. Нажал ли юзер кнопку, кликнул ли мышью - система ответит ему именно тем действием, которое он ожидает. В принципе это наверное здорово, кодеры должны быть благодарны, ведь часть их работы уже сделана. Но как все это соотносится с эргономикой?
А получается, что никак. Точнее не просто "никак", а скорее даже прямопротивоположно.
Например, у вас, как у любого нормального пользователя, уже в подсознании "зашито", что двойной клик приводит к редактированию или запуску. Но вот МС считает, что в дереве дабл-клик должен приводить к сворачиванию/разворачиванию узлов. Попытка переопределить событие DoubleClick на вызов окна редактора приводит к успеху - окно вызывается и работает, но после его закрытия снова срабатывает "стандартное" действие - сворачивание или разворачивание узла. Избавиться от этого "улучшения" я не смог.
Другой пример - DataGridView. Попытка перехватить событие нажатия клавиш так же срабатывает успешно, но если вы нажмете Enter, то после обработки события библиотека самозабвенно с милой улыбкой передвинет указатель текущей записи на следующую. Это поведение так же не лечится.
Кстати, Вы знаете, что DataGridView имеет свойство AutoGenerateColumns? Авторы учебников по C# о нем знают, в MSDN оно так же описано, даже IntelliSence его признает, но вот в окне Properties можете его не искать - мелкомягкие решили, что на этапе проектирования разработчику оно не понадобится, поэтому в "Свойствах" его нет.
Позже буду дополнять эту тему, т.к. я уверен, что описанное здесь - только вершина айсберга.
Залепа №6. Вечный календарь и пляска с бубном.
Ситуация:
Есть некоторое событие, достаточно жестко привязанное к конкретным датам. Например поездки с проверками некоего крутого начальника. И этому начальнику надо знать, в какие поездки брать с собой помощника, а в какие нет. Сознаюсь, задача слегка синтетическая, но поразмыслив немного, вы сами найдете кучу вполне реальных задач, сводящихся к этой.
Итак, секретарше в календаре надо видеть дни, в которые начальник выезжает и как-то особо метить дни, в которые начальник будет брать с собой помощника. Как это сделать программно? Да очень просто, ведь у нас есть супер-мега-контрол MonthCalendar.
Кроме всех "обычных" прелестей, эта мега-кульная штука умеет еще и метить дни. Причем метки можно ставить аж трех разных типов, включая ежемесячные события. К слову сказать, диапазон у этого календаря тоже удовлетворит любого - он умеет работать с датами до 9999 года, так что очередная "проблема 3000" нам уже не грозит. Можем писать софт даже не на века, а на тысячелетия! Действительно огромное достижение инженерной мысли.
Ну вы уже конечно догадались, что и здесь есть все то же пресловутое "НО".
На этот раз это "НО" вылилось в то, что все эти разнообразные отметки (напомню, что их аж три разных типа) на экране выглядят абсолютно одинаково. Причем не просто одинаково, а написаны тем же шрифтом, что и обычные даты, только слегка жирненьким.
Майкрософт напихало в этот контрол кучу свойств и методов, из которых на практике используется едва ли 5%, но пожалело ввести хотя бы одну переменную, чтобы задать цвет отмеченных дат. Жмоты! Правда, в вышеописанной задаче, одним цветом мы бы все равно не обошлись, но было бы хоть что-то. А так нет. :(
Теперь финальный аккорд.
Контрол MonthCalendar (кстати, как и многие другие в .NET) не имеет обработчика для собственного рисования дат. Этим МС вбило последний гвоздь в нашу попытку с помощью их мега-библиотеки решить поставленную (к слову сказать достаточно простую) задачу, по созданию удобного интерфейса.
Выход только один - писать свой контрол, со всеми вытекающими. :(
Залепа №5. Мы строили, строилаи и ... ничего не построили :(
Одна из особенностей .NET, которую создатели превозносят до небес - строгий контроль типов. Это значит, что теперь что попало чему попало не присвоишь. Хорошо или плохо это - тема отдельная и достаточно большая. Но я хочу поговорить немного о другом.
Если теперь система сама с точностью до запятой знает какой тип имеет каждая переменная, то зачем программисту вручную делать приведение типов? Почему компилятор не может взять эту рутину на себя?
Давайте рассмотрим пример.
MyClass r = new MyClass(); Object o = r; MyClass x = o; // (1) MyClass x = (MyClass) o; // (2)
Вариант (1) не компилируется, в то время как (2) проходит компиляцию на ура. Но как работает в этом случае скомпилированная программа? А работает она так: когда дело доходит до преобразования Object в MyClass, CLR проверяет, соответствует ли значение в переменной о типу MyClass и, если это так, то производит присваевание. Иначе мы получим исключение.
Подчеркну, что это происходит во время выполнения, а не компиляции. Т.е. если во время разработки мы напишем что-нить типа: String x = (String) o;, то это тоже откомпилируется нормально и про ошибку мы узнаем только в рантайме.
Возникает вопрос:
если на момент компиляции мы можем написать любую чушь, и в откомпилированной версии все равно будет присутствовать проверка правильности типа, а ошибки начнут вылазить только когда CLR проверит эти самые типы, то почему нельзя просто записать MyClass x = o; вместо MyClass x = (MyClass) o; ведь результат компиляции и результат работы все равно будет одинаковым?...
Впрочем, глядя на патологическую любовь мелкомягких к длинным идентификаторам и десяткам дублирующих функций, можно с уверенностью сказать, что они все страдают графоманией - болезнью, которая заставляет пациента писать, писать и писать. При этом совершенно безразлично, что именно писать - повторные указания на преобразование типов, сотни одинаковых модификаторов доступа или out'ы и "ref'ы, которые совершенно бесполезны. Главное писать и побольше. Этой же болезнью они пытаются заразить и конечных пользователей своих супер-продуктов - нас с вами, выдавая свою патологию за мега-знание и ультра-крутость. :(
