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


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, нужного результата достигнуть не сложно.
Дерево с несколькими колонками

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

Blend и Visual Studio 11 Developer Preview


После установки Visual Studio 11 Developer Preview на 64-х битной Windows 7, перестал запускаться Expression Blend, выдавая ошибку в clr.dll. Для исправления данной проблемы необходимо запустить командную строку с административными правами и выполнить следующие команды:
%windir%\Microsoft.NET\Framework\v4.0.30319\ngen uninstall "%ProgramFiles(x86)%\Microsoft Expression\Blend 4\Microsoft.Expression.Framework.dll"
 
%windir%\Microsoft.NET\Framework\v4.0.30319\ngen uninstall "%ProgramFiles(x86)%\Microsoft Expression\Blend 4\Microsoft.Expression.Blend.dll"
 
%windir%\Microsoft.NET\Framework\v4.0.30319\ngen uninstall "%ProgramFiles(x86)%\Microsoft Expression\Blend 4\Microsoft.Expression.Project.dll"
 
%windir%\Microsoft.NET\Framework\v4.0.30319\ngen uninstall "%ProgramFiles(x86)%\Microsoft Expression\Blend 4\Microsoft.Expression.WindowsPhone.dll"

Сплэшскрин в 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, неудобно и ресурсоёмко.

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 операциями, так что похоже придётся обойтись без них, разве что придумаю эффекты работающие в целых числах.

Microsoft WPF Ribbon


Итак, свершилось то, чего мы ждали многие годы (ну, если честно, то лично мы-то забросили ждать ещё в ноябре прошлого года, начав Fluent) - микрософты выпустили Ribbon for WPF.
Microsoft WPF Ribbon

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

Странный баг в 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 исправится ли данный баг или нет?

Немного про шаблоны 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

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

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.

Работа с zip-архивами


Всё таки в Microsoft были неправы, сделав интернальными столько полезных классов в .Net Framework.
Вот например, работа с *.zip файлами. Класс есть, но он интернальный, а возможность работать дана тока с пакэйджами (package - это такие zip-архивы, которые содержат Content_Types.xml, например документы 2007-го офиса). И вот зачем спрашивается надо было закрывать? Пришлось воспользоваться рефлекшеном для работы:
Assembly asm = Assembly.GetAssembly(typeof (ZipPackage));
Type ZipArchiveType = asm.GetType("MS.Internal.IO.Zip.ZipArchive");
Type ZipFileInfoType = asm.GetType("MS.Internal.IO.Zip.ZipFileInfo");
MethodInfo openOnStreamMethod = ZipArchiveType.GetMethod("OpenOnStream", BindingFlags.Static | BindingFlags.NonPublic);
object archive = openOnStreamMethod.Invoke(null, new object[] {stream, FileMode.Open, FileAccess.Read, false});
MethodInfo getFileMethod = ZipArchiveType.GetMethod("GetFile", BindingFlags.NonPublic | BindingFlags.Instance);
object contentFile = getFileMethod.Invoke(archive, new object[] {"content.xml"});
MethodInfo getStreamMethod = ZipFileInfoType.GetMethod("GetStream", BindingFlags.NonPublic | BindingFlags.Instance);
using (Stream contentStream = (Stream)getStreamMethod.Invoke(contentFile, new object[] { FileMode.Open, FileAccess.Read }))
{
// Здесь можно без проблем использовать распакованные данные
}

Метки: c#dotnetzip

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


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

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

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


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

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