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


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

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

Fluent 2.0


Сегодня, ровно через год после начала разработки Fluent-а мы выпустили долгожданную версию 2.0.

Fluent v2 preview


Выпустили сегодня превью долгожданного Fluent-а v2. Некоторые вещи ещё не закончены, но в целом оно уже близко к тому, что мы планировали.

Microsoft WPF Ribbon


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

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

Fluent добрался до первого места по highest ranking в Visual Studio Gallery


Ха, Fluent добрался до первого места по highest ranked в Visual Studio Gallery.

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

Silverlight и WPF


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

Fluent 1.3


Да, мы сделали это - Fluent дорос до версии 1.3.
Fluent 1.3
Теперь ещё лучше, ещё быстрее и ещё надёжнее. Есть версии как под .NET 3.5 так и под .Net 4.0

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

Fluent - релиз


Сегодня мы выпустили первый релиз Fluent-а
Fluent - релиз
Оно уже вполне жизнеспособно, есть ещё кой-какие баги, но они по большей части связаны с контекстными меню и quick access toolbar-ом, которым почти никто не пользуется.
В общем несмотря на некоторые недостатки это лучше чем все бесплатные аналоги, а местами и лучше чем платные (что, впрочем, не удивительно, учитывая крайне невысокое качество последних), так что как пофиксим все мелочи да доработаем темы, то обойдём и платных :)
В общем всячески рекомендую - самые правильные риббоны для WPF-а

PS. Остальные скриншоты здесь.

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-а тоже), а то продаваемые сторонними конторами контролы в большинстве своём абсолютно никакие.

Fluent CTP2


Выпустили таки сегодня второй CTP риббонов. Издалека даже похожи на настоящие, хотя конечно до того, чтоб их можно было использовать в рабочем проекте ещё месяца полтора работы (чтоб там кто не думал по этому поводу). В целом не могу не заметить, что риббоны оказались значительно более сложным контролом, чем я предполагал (это вам не TabControl с кнопочками, все гораздо сложнее) и многие аспекты их поведения до сих пор вызывают у меня сомнение, а хваленый гайд от микрософт по риббонам просто не обговаривает многие моменты или обговаривает их очень условно, плюс некоторые вещи очень плохо сочетаются с WPF-ным представлением о том как должны работать контролы (луч ненависти тем, кто разрабатывал Popup-ы и систему фокусов, ну вот зачем было такую жуть городить). К слову разработка сложных контролов под WPF оказалось вещью крайне нетривиальной и далеко переплевывающей по разным спецэффектам разработку под WinAPI: временами у нас вылазили крайне специфические глюки, которые впрочем мы успешно (я надеюсь) побороли, хотя некоторые вещи так и остались нам не ясны. Надо бы как-нибудь подробнее описать разработку сложных lookless-контролов для WPF-а, надеюсь в ближайшее время у меня дойдут до этого руки.
Fluent CTP2
PS. К слову под WPF до сих пор нет ни одних риббонов в достаточной мере соответствующих тем, что были представлены в 2007-ом офисе, и это не смотря на весьма немаленькие цены на эти риббоны. Всё что нам довелось посмотреть (а мы смотрели всё, что смогли найти) имело те или иные отличия в поведении, временами весьма нехилые (что особенно странно при цене 300 баксов за контрол на одного разработчика). На удивление под WinAPI, MFC, WinForms и даже Delphi (оно ещё живо?) имеются вполне приличные риббоны (значительно превосходящие любой WPF-ный аналог). Я уж не говорю про майкрософтские scenic-риббоны, которые по ощущениям вообще основаны на коде вытянутом из 2007-го офиса.
PPS. Впрочем, вообще все коммерческие контролы для wpf-а не вызывают у меня никакого восторга. Честно говоря, возникает стойкое ощущение, что их разработчики толком не освоили WPF и многие используемые ими решения гармонично бы смотрелись в WinForms-контролах, а отнюдь не в WPF-ных, что, учитывая весьма немалую цену этих контролов, вызывает у меня стойкую мысль о крупном надувательстве тех пользователей, которые их покупают.
PPS. Заняться что-ли созданием правильных WPF-ных контролов, да продажей их по демпинговым ценам, чтобы всяким там не повадно было всякую херню выпускать.
PPPS. А вообще когда уже микрософты .NetFramework4 RC выпустят: я уже хочу на него мигрировать, все эти размытости и непонятности со шрифтами в WPF-е надоели до крайности.

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


В 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

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

Bling


Какую славную библиотечку для wpf-а я отрыл. Просто полный отпад. Особо радует возможность писать пиксельные шейдеры без возьни с hlsl-ем - это просто пять с плюсом. Я в глубоком восторге, хоть и не все шейдеры работают (выдают какие-то ошибки компиляции, судя по всему, связанные с тем, что конверсия числа в строку идёт с системными параметрами и, соответственно, вместо точки, дробная часть отделяется запятой).

Метки: wpfhlslc#

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)
    {
        // Здесь даблклик
    }
}
Тем же способом можно получить и тройной клик и т.д.

NearestNeighbor у BitmapScalingMode


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

Очередной баг в WPF


Наткнулся сегодня в WPF на неприятный баг - если у окна установить ResizeMode в ResizeWithGrip, то из другого потока уже не получится создать окно с ResizeMode = ResizeWithGrip. Поскольку при этом выскакивает ошибка доступа к Brush из другого потока. Как я понимаю, это связано с тем, что либо стиль окна у них там кэшируется, либо Brush, либо ещё что-то. Всегда подозревал, что для локальных ресурсов кэширование - это зло. Час убил на этот баг. (Что-то я сегодня торможу :) первый день после трёхдневного выходного сказывается. К слову как-то раз на такой фокус мы нарывались и с BitmapImage, но там это лечилось просто отключением кэширования либо Freeze.

PS. Хотел было мелкософтам отписать о баге, да лень стало это на ангельском формулировать. Ладно, глядишь кто другой отпишет.

Метки: bugswpfc#

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


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

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

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


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

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