Все записи с меткой 'programming'


XamlCombine


Для Fluent-а и ряда других проектов я написал небольшую утилиту для объединения нескольких xaml-овых Resource Dictionary в один большой xaml.
Данная утилита:
  1. считывает список словарей, которые надо объединить из файла;
  2. загружает ресурсы из этих словарей;
  3. собирает список используемых namespace-ов и удаляет повторяющиеся;
  4. сортирует загруженные ресурсы в порядке их использования (т.е. первыми окажутся те ресурсы, которые будут использоваться последующими);
  5. заменяет DynamicResource на StaticResource;
  6. сохраняет полученный словарь ресурсов в файл.

Командная строка, для работы с утилитой:
XamlCombine.exe list-of-xamls.txt result-xaml.xaml
Где:
  • list-of-xamls.txt - текстовый файл содержащий список xaml-овых словарей, которые необходимо объеденить,
  • result-xaml.xaml - имя результирующего xaml файла.

Я предпочёл использовать один большой xaml, а не набор смерженых (merged), потому что:
  1. при использовании одного xaml-а увеличивается скорость загрузки приложения и уменьшается кол-во занимаемой памяти;
  2. в едином xaml-е можно использовать StaticResource заместо DynamicResource, что также даёт прирост производительности;
  3. нет проблем с Generic.xaml для библиотек с lookless контролами.

В ближайшее время планируется:
  • ввести возможность отключения замены DynamicResource на StaticResource;
  • ввести возможность отключения сортировки ресурсов;
  • ввести поддержку включения merged словарей (в данной версии они удаляются).

Страница проекта на CodePlex-е.

Доступ к ViewModel списка из контекстного меню элемента списка


Недавно возник следующий вопрос. Есть ListBox, элементы которого берутся из коллекции ViewModel. Их вид задаётся через ItemsTemplate. В ItemsTemplate задано контекстное меню. Необходимо добавить в это контекстное меню MenuItem, заголовок которого брался бы из ViewModel.
Доступ к ViewModel списка из контекстного меню элемента списка

Читать далее...

Дерево с несколькими колонками


Стандартный TreeView в WPF, казалось бы, не позволяет сделать многоколоночное дерево. Но, как оказалось на практике, немного пошаманив с DataTemplate и Binding, нужного результата достигнуть не сложно.
Дерево с несколькими колонками

Читать далее...

Сплэшскрин в WPF


В .NET Framework 3.5 SP1 появилась возможность использовать в качестве сплэшскрина картинку из ресурсов. Для этого необходимо было поставить у картинки Build Action в SplashScreen, либо в коде использовать класс SplashScreen. Но данный сплэшскрин был очень ограничен в своих возможностях. На него даже невозможно было вывести текст. И если при старте программы была необходимость выводить сплэшскрины с разным текстом, то приходилось создавать множество вариантов картинок, со всеми возможными надписями. Как вариант можно было сделать отдельно фоновую картинку и отдельно картинки с надписями и показывать два сплэшскрина один поверх другого (такой метод мы использовали в ТЕХНОкоорд 5.0), но в данном случае был возможен вариант, когда пользователь ткнёт мышкой в фоновый сплэшскрин и он перекроет сплэшскрин с текстом. Также как вариант можно сначала показывать простой сплэшскрин из картинки, а потом когда загрузятся нужные сборки показывать WPF-ное окно, как сплэшскрин, так например поступает Expression Blend. Но такой вариант имеет смысл, если у вас ещё после инициализации WPF-а происходит загрузка большого количества данных, или использовать как сплэшскрин только WPF-ное окно - это вообще не вариант (мы пробовали это в 4-ом ТЕХНОкоорд-е), поскольку к тому времени, как такой сплэшскрин появится на экране, уже загрузится главное окно приложения.
Сплэшскрин в WPF
А потом появилась бета-версия Microsoft Office 2010, с очень красивым анимированным сплэшскрином, и мне захотелось использовать похожие сплэшскрины в моих приложениях на WPF-е. Поэтому был создан класс ExtendedSplashScreen, который позволяет создавать гораздо более богатые сплэшскрины, чем стандартный WPF-ный SplashScreen. Модифицированная версия этого класса применяется в тестовых сборках ТЕХНОкоорд-а 6.0.

Читать далее...

Множественное выделение в дереве используя M-V-VM


Стандартный WPF-ный TreeView не поддерживает возможность множественного выделения. Поэтому в том случае, когда это необходимо приходится либо пользоваться сторонними коммерческими контролами (которые, как правило, весьма невысокого качества), либо реализовывать свой вариант дерева, что является достаточно нетривиальной задачей. Но если вы в своём проекте используете шаблон проектирования Model - View - ViewModel (M-V-VM), то реализовать множественное выделение можно значительно более простым путём.
Множественное выделение в дереве используя M-V-VM

Читать далее...

Аккордеон


Недавно мне пришла в голову мысль, что такой контрол, как Аккордеон(Accordion) в своём классическом варианте с одним активным pane-ом, функционально является полным аналогом TabControl-а, просто в другом визуальном оформлении. И я решил реализовать стиль для TabControl-а, который бы превращал его в аккордеон.
Аккордеон

Читать далее...

Кнопки как в супербаре Windows 7


Ещё начиная с момента выхода Windows 7, мне хотелось сделать на WPF-е стиль для кнопок, такой же как в супербаре. И наконец-то у меня дошли до этого руки.
Кнопки как в супербаре Windows 7

Читать далее...

Баг с роутингом в ASP.NET MVC под 4-ый .NET Framework


Полгода назад я нашёл странный баг в ASP.NET MVC 2 под .NET Framework 4. Сегодня у меня наконец дошли руки разобраться в чём там дело и как это обойти.

Читать далее...

Рендер под Windows CE


Экспериментальным путём установил, что рендеринг Bitmap-а под Windows CE занимает минимальное время, если формат изображения соответствует формату системы, в большинстве случаев это - 16 бит на цвет по 5-6-5 на компонент. Пришлось допилить библиотечку для работы именно в таком формате, а не в RGB32, как было (впрочем поддержку RGB32 я оставил на всякий случай).
Также написал библиотеку для работы с DirectShow, чтоб проигрывать музыку и, в будущем, видео. Также написал поддержку извлечения тэгов и mp3 и wma файлов, поскольку использовать для этого DirectShow, неудобно и ресурсоёмко.

Деградация и полный упадок


На RSDN-е эпический тред про то, как нарисовать рамочку для выделения ala MS Paint. Такого кретинизма я не видал, наверное, со времён чтения нам в институте курса по программированию под Windows (или как это там называлось). К слову, курсовой, по этому самому программированию под Windows, у меня был клон Paint-а, и рамочки там даже не думали тормозить и моргать. Да что там, у меня на 3-ем пне трёхмерный кубик на весь экран вертелся со скоростью под 30 кадров в секунду, а написан он был на голом GDI, без всяких извращений. А они на GDI+ рамочку без тормозов и морганий не могут вывести. Деградация и полный упадок, RSDN выродился окончательно и бесповоротно.

PS. Всё, на русскоязычные форумы я больше ни ногой, они подрывают моё психическое здоровье и веру в светлое будущее российского программирования.

Windows CE


После покупки в машину проигрывателя основанного на Windows CE, меня самым естественным образом потянуло написать более пристойную оболочку, чем жуткое разноцветное творение китайцев. Поэтому я активно принялся экспериментировать с различными графическими библиотеками под Windows CE. Результат оказался печальным: во-первых 90% библиотек были заточены под Windows Mobile и на CE просто не запускались, а во-вторых у меня на устройстве оказалась настолько урезанная версия Windows CE, что в неё отсутствовал DirectDraw и даже не работали функции WinApi для альфа-блендинга.
Windows CE
Поэтому пришлось написать свою маленькую библиотечку по работе с графикой. Низкий уровень библиотеки написан на C++ (думаю в будущем переписать на ассемблер, но лень пока побеждает), высокий на C#. Идеологически библиотека пытается реализовывать что-то напоминающее M-V-VM, только с огромными ограничениями. По причине неработоспособного DirectDraw, для вывода на экран, используется GDI-шный DrawBitmap, он не очень быстр (подозреваю, что тут дело в неверной битности изображения), но учитывая ориентацию на рендеринг пользовательского интерфейса, производительности должно хватить.
Впрочем хотелось бы добавить каких либо эффектов, но на устройстве очень туго с floating-point операциями, так что похоже придётся обойтись без них, разве что придумаю эффекты работающие в целых числах.

Странный баг в ASP.NET MVC 2


Есть у меня проект на ASP.NET MVC 2, и есть там такой Route:
routes.MapRoute(
                "Archive", // Route name
                "archive/{year}/{month}/{day}", // URL with parameters
                new { controller = "Archive", action = "Overview", year = string.Empty, month = string.Empty, day = string.Empty }, // Parameter defaults
                new { year = @"(\d\d\d\d)?", month = @"\d?\d?", day = @"\d?\d?" }
            );
и соответственно я потом строю Url таким методом:
Url.RouteUrl("Archive", new {action="Overview", year = string.Empty, month = string.Empty, day = string.Empty});

Так вот если компилировать данное приложение под .NET 3.5, то все работает, возвращается правильный url, а вот если под 4-ый то возвращается null. Соответственно возникают вопросы: 1-ый может я где-то в корне не прав, 2-ой какого дьявола никто кроме меня на такое не нарывался (по крайне мере гугл и бинг молчат об этом) и 3-е если я сконвертирую проект под ASP.NET MVC 3 Preview исправится ли данный баг или нет?

Silverlight и WPF


Эх, все таки Silverlight проигрывает WPF-у по удобству использования, столько ограничений, местами весьма бессмысленных. Когда же они доведут его до более менее близкого по эффективности к WPF-у продукта.

Немного про шаблоны ContentControl-ов


Почему-то большинство людей, которым доводилось делать ControlTemplate-ы для ContentControl-ов никогда не используют возможность ограничить тип этого самого контента. Например если у нас есть кнопка, про которую мы точно знаем, что там будет только картинка, то почему не задать её шаблон следующим образом:
<ControlTemplate  TargetType="Button">
    <Border>
        <Image Source="{TemplateBinding Content}"/>
    </Border>
<ControlTemplate>
И тогда в xaml-е можно ее будет задавать следующим образом:
<Button>Images/Image1.png</Button>
Вместо традиционного:
<Button><Image Source="Images/Image1.png"/></Button>
Получается короче и удобнее в использовании. Естественно, использование данной возможности накладывает ограничение на использование таких шаблонов в незапланированных целях, поэтому допустим применять такую возможность в библиотеках компонентов будет не лучшей идей, но для использования внутри конкретного законченного проекта будет вполне удачно для упрощения и уменьшения написанного xaml-а.

IsAsync в биндинге


Заметил, что если поставить у биндинга свойство IsAsync в true, то он не будет тормозить при загрузке, если в во ViewModel-и коллекция создана как-то так:
private ObservableCollection<string> stringCollection;
public ObservableCollection<string> stringCollection
{
    get
    {
        if(stringCollection==null)  stringCollection = FillStringCollection();
        return stringCollection;
    }
}
Т.е. он загрузит коллекцию асинхронно, соответственно если ещё поставить триггер на null, то можно рисовать красивую анимацию загрузки, что весьма удобно при больших объёмах данных.

Размер Thumb-а у ScrollBar-а


В общем и целом WPF мне нравится. Вещь замечательная, удобная и не имеющая аналогов. Из более менее близких можно назвать пожалуй Qt, благо после покупки Нокией он стал развиваться гораздо активней и в целом движется в относительно верном направлении. Ещё конечно можно назвать Htmlayout, но он все таки слегка из другой оперы, хоть на данный момент и является единственной возможностью создавать красивые нативные приложения под Windows (Qt я нативным не считаю, ибо это монстр ещё похлеще .Net). Так вот, WPF мне нравится, но иногда там встречаются настолько нетрадиционные решения, что волосы дыбом встают. Вот например есть скроллбар (ScrollBar) и мы хотим задать Thumb-у этого скроллбара некую минимальную высоту (или ширину в зависимости от того вертикальный ли это скроллбар или горизонтальный). Казалось бы что проще, ставишь MinHeight Thumb-а в нужное значение и наслаждаешься полученным результатом. А вот нет. Основной поведенческой логикой скроллбара заведует некий Track, который нисколько не волнуют всякие там MinHeight-ы и который тупо урезает Thumb до того размера, до которого сочтёт необходимым. После долгого ознакомления с MSDN-ом, выяснилось следующее: для минимального размера Thumb-а Track использует константу SystemParameters.VerticalScrollBarButtonHeightKey (точнее половину от значения этой константы), которая по умолчанию связана с дефолтным значением в Windows. И эту константу можно поменять в ресурсах Track-а примерно таким образом:
<Track.Resources>
  <sys:Double x:Key="{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}">100</sys:Double>
</Track.Resources>
Век живи, век учись, так руки бы и оторвал тем индусам, которые такое наворотили.
К слову не могу не заметить, что ни в одном из видимых мною платных WPF-ных контролов, в котором был кастомный стиль на скроллбар, не было задано нужной минимальной высоты, поэтому во всех них наблюдались некоторые баги при достижении минимального значения. И это определённо свидетельствует о недостаточном качестве этих самых контролов. Вот посмотришь на чужие контролы и так и хочется заняться создание правильных контролов для WPF-а (и silverlight-а тоже), а то продаваемые сторонними конторами контролы в большинстве своём абсолютно никакие.

Стиль для круглой кнопки


В Window Vista (а также судя по бета версии и в Windows 7) кнопка "Пуск" перестала выглядеть как унылый прямоугольник, и стала красивой круглой. Также аналогичная кругла кнопка была использована в Windows Media Player, в Windows Photo Viewer , в Windows Live Gallery и, с другой расцветкой, в Microsoft Office 2007.
Стиль для круглой кнопки
Реализовать аналогичную кнопку в WPF достаточно легко.

Читать далее...

Тултипы как в офисе 2007


В 2007-ом офисе появилось множество всяческих достаточно интересных элементов управления. В том числе достаточно привлекательная всплывающая подсказка (tooltip).
Тултипы как в офисе 2007

Читать далее...

Выпадающий по нажатию на кнопку Popup


Собственно говоря я совсем не собирался писать о такой элементарной вещи, как выпадающий по нажатию на кнопку Popup, если бы не увидел, как некоторые выполняют эту достаточно примитивную операцию путём написания обработчика клика кнопки и присваивания в нем IsOpen=true (а некоторые особо извращённые ещё и позиционируют попап прям в коде используя PointToScreen/PointFromScreen).
Выпадающий по нажатию на кнопку Popup

Читать далее...

Просмотрщик XPS


В свое время, вместе с выходом висты, если я не ошибаюсь, компания Microsoft ввела такой формат как xps. Этот формат вроде был призван потеснить адобовский pdf, но микрософт не утрудили себя каким-либо его продвижением. В целом формат достаточно неплох для такого рода вещей, как всякие отчёты, мануалы и прочие документы не требующие модификации. Вот только присутствует один большой недостаток. У данного формата отсутствует толковый просмотрщик, поскольку просматривать его предлагают в интернет эксплорере, с помощью плагина который шёл в комплекте с вистой, а в xp и 2003 ставился вместе с 3-им дотнет фреймворком, что крайне неудобно, плюс просмотрщик внутри ie не поддерживает, ни структуры документа, ни внутрених ссылок. В общем достаточно хороший формат был бездарно загублен убогим просмотрщиком. Чуть позже в микрософте опомнились и сварганили Xps Essentials Pack, который несмотря на пафосность названия и представлял собой вполне нормальный (за исключением того, что этого просмотрщика существует как минимум 4 разных версии, под разные версии windows) просмотрщик для этого самого xps-а. Плюс в windows 7 такой просмотрщик(явный наследник essential pack) включён по умолчанию, плюс плагин для ie серьезно доработан.
Так вот, чему я это все. А к тому, что в 3-ем дотнет фреймворке встроена функциональность для работы с этим самым xps-ом. И сейчас я покажу, как написать свой просмотрщик для него.
Просмотрщик XPS

Читать далее...

ColorPicker на WPF


Нашел статейку (http://www.codeproject.com/KB/WPF/WPF_CustomerControl.aspx) про то как делать собственные контролы на WPF. Если не придираться к использованию терминов и формулировкам, то с приведенным способом написания своих контролов можно согласиться. А вот выбранный пример абсолютно неадекватен, т.к. ColorPicker в WPF можно сделать гораздо проще и быстрее с помощью DataTemplate.
ColorPicker на WPF

Читать далее...

TextBox с описанием и картинкой в WPF


Недавно с ужасом заметил, что для создания TextBox с описанием (не знаю как это правильно называется: в общем, когда в TextBox нет текста и фокуса, там написано, что это за поле ввода, как в висте в проводнике в правом верхнем углу окошко поиска) некоторые люди создают новый UserControl, тогда как гораздо проще(и с гораздо меньшим количеством кода) можно сделать это стилями и ControlTemplate.
TextBox с описанием и картинкой в WPF

Читать далее...

Невидимые контролы


Экспериментальным путём обнаружил следующую вещь: для невидимых контролов лучше ставить Visibility не Hidden, а Collapsed. Это очень сильно влияет на производительность в случае, когда они меняют размеры, особенно если используются в СontrolTemplate.
А вообще, наконец-то, оценил всю мощь DataTemplate: писать такие вещи парой строчек кода - это круто. Но что-то производительность меня не очень радует, хотя основную часть я конечно оптимизировал.

Double click в WPF-е


Обнаружил, что для контролов, у которых отсутствует OnMouseDoubleClick, обработчик двойного клика можно получать следующим способом:
private void OnItemMouseDown(object sender, MouseButtonEventArgs e)
{
    if(e.ClickCount==2)
    {
        // Здесь даблклик
    }
}
Тем же способом можно получить и тройной клик и т.д.

Создал тестовый проектик на XNA для Zune


Наваял тестовый проект на XNA под Zune, с ходящим роботом (гандамчег, с турбосквида скачал)
Создал тестовый проектик на XNA для Zune
Обнаружилась редкостная гадость: проклятая Zune понимает исключительно единственный формат картинки - 32-х битный, а учитывая 16-ти метровое ограничение на память это выглядит крайне печально, ибо только анимации хождения для робота весят 2,5 метра. Походу придётся придумывать, как использовать подгрузку данных с жесткого диска. Эх, нет чтоб поддерживать мой любимый l4a4.

NearestNeighbor у BitmapScalingMode


Узнал, что в SP1 к Net Framework 3.5 у BitmapScalingMode наконец-то ввели мод NearestNeighbor, т.е. теперь изображения можно растягивать без сглаживания (с жуткими пикселями), помнится года два назад мы сильно мучились пытаясь достичь данного эффекта, но так и не достигли, а нынче просто подарок судьбы.

Внезапно


День великих открытий: я до сих пор не знал, что можно так делать:
public bool IsUsing
{
      get { return (bool)GetValue(IsUsingProperty); }
      private set { SetValue(IsUsingPropertyKey, value); }
}

MS Source Analysis


Microsoft-ы выпустили MS Source Analysis for C#, в отличии от FxCop, который анализируют уже скомпилированный код, эта утилита проверяет исходники на соответствие правилам (а правила там зверские, но их можно отключать/подключать). Также её вроде можно встроить в MSBuild и проверять на корректность кода на этапе компиляции. В общем отличная штука.
PS. В рабочем проекте в каждом файле под тысячу нарушений, впрочем, учитывая, что мы кодируем по своим правилам, а не по тем, что заложены в этой утилите, не удивительно.

Размышления на тему обучения программистов


Размышления на тему того, как надо правильно обучать программистов, навеяно комментариями к этому.
Итак, школьные годы:
1-4 классы: общее знакомство с компьютером, Windows там, MS-DOS (командную строку учить необязательно, а вот Norton Commander как минимум на уровне копирования файлов и запуска игр)
5-7 классы: знакомство с программированием, основы алгоритмизации, на примере какого-нибудь лого (кенгурёнка и прочих кукарач)
8-11 классы: алгоритмизация, лучше всего на Turbo Pascal 5, на крайний случай сойдёт и TP 7, главное никакого Delphi, иначе детей можно будет считать потерянными для мира программирования. Также можно использовать Basic (само собой под DOS), но паскаль в данном случае будет лучше
Институт:
1-ый курс: старый добрый C, основная цель курса обучить студента правильно работать с указателями и прочим стандартным вещам
2-ой курс: ООП, в основном теория, примеры на C++, но не забывая упоминать про прочие типа Smalltalk-а, Java, C# и т.д...
3-ий курс: обучение правильному построению архитектуры приложений, рефакторингу/отладке/тестированию/профайлингу и т.д. и т.п. Плюс основы функционального программирования. Факультативы по Java, C# и прочим(именно по языкам, никакого формошлепства и прочего визуального программирования). Также неплохо давать основы WinAPI, предпочтительно с какой-нибудь навороченной курсовой в конце семестра. Также как факультатив возможно введение в web-программирование, хотя это совсем не обязательно.
4-5 курсы: практика, практика, и ещё раз практика. Само собой в реальных проектах, в реальных фирмах, никакой теории уже не надо. С этого момента студенты должны учиться на своём опыте и на опыте старших коллег. Естественно это требует тесного взаимодействия ВУЗов и предприятий, чего сейчас нет и в помине.

Краткие примечания
- я считаю, что для обучения школьников наиболее подходящим языком будет Pascal (именно старый добрый процедурный паскаль, а ни в коем случае не жутчайшие Delphi или Object Pascal)
- основной недостаток паскалистов (большинства по крайне мере) - это абсолютное неумение работать с памятью, именно поэтому на первом курсе института этому должно уделяться особое внимание
- ни в коем случае нельзя использовать для обучения Deplhi(а также CBuilder, Visual C# и прочие IDE, где доминирует формошлепство), ибо как показывает практика большинство людей начавших с формошлепства так никуда и дальше и не продвигается, именно поэтому я считаю, что закупка в школы BDS`а приведёт к тому, что хороших программистов станет значительно меньше (впрочем их и так совсем немного), а вот всяких быдлокодеров, которые только и умеют, что раскидывать кнопки по форме, станет просто немерено (хотя их и так немало)
- по настоящему хороший программист без особых проблем сможет сменить язык программирования на другой(имеются ввиду естественно императивные языки, с функциональными есть своя специфика), конечно в каждом языке есть свои тонкости, но основа-то в конечном итоге у всех одна, поэтому не играет большой разницы C это, Pascal, Basic или что-то ещё.

PS. Всё это моё личное мнение, навеянное жизненным опытом, и совсем не претендующее на стопроцентную объективность.

Работа с неклиентской областью окна


Давно собирался написать о том, как сделать окно с элементами в неклиентской части. Такое, как, например, в 2007-ом офисе.
Работа с неклиентской областью окнаРабота с неклиентской областью окна

Читать далее...

Окошко в стиле Yahoo Messenger


Увидел недавно Yahoo Messenger for Vista и решил сделать аналогичное окно.
Окошко в стиле Yahoo Messenger

Читать далее...