Category Archives: WPF (.Net 3.0)

Курсы доллара и евро: гаджет для висты

Давненько хотел написать какой нить гаджет для висты. Изначально хотел сделать это на WPF, но выяснилось что к гаджетам у микрософта другой подход. Посути гаджет – это html веб страница со всеми вытекающим. Поэтому только xbap или silverlight можно засунуть в гаджет (причем стало это можно сделать относительно недавно).

Посмотрев в каталоге гаджетов, гаджеты, которые показывают курс валют, и не найдя там ничего интересного, я решил написать свой монитор курсов. У нашего центрабанка есть прекрасный веб сервис, который предоставляет всю информацию о курсах валют за любой период.

Попытка использовать сильверлайт закончилась неудачно. Во первых, под 64-битной вистой сильверлайт не работает в 64-битном сайдбаре. Это можно обойти, запуская 32-ух битную версию сайдбара, но это уже извращение. Во вторых, из сильверлайта в гаджете нельзя нормально обратиться к вебсервису. Это связано с тем, что сильверлайт в гаджете не видит конфигурационных xml файлов и не может получить доступ. Есть workaround, который передает данные в сильверлайт контрол через скрипт AJAX, но я считаю это не очень красивым. 

В итоге я сделал проще – гаджет просто показывает картинку с вебсервера, обновляя ее раз в час. А на сервере работает php скрипт по крону, который запрашивает данные у центробанка. Гаджет показывает текущий курс бакса и евро, на сколько он изменился за день и за неделю и график динамики курсов за 3 недели. 

Гаджет курса валют ЦБ для висты

Скачать гаджет

Просто запустите скаченный файл, и гаджет установится. Если этого не произойдет и он откроется как зип архив, то можно на гаджете нажaть Open with… Sidebar. Если и это не поможет, то можно создать папку C:\Users\Ваше имя\AppData\Local\Microsoft\Windows Sidebar\Gadgets\CurrencyRates.gadget\ и в нее скопировать содержимое архива. 

Релиз .NET Framework 3.5SP1 и VS2008 SP1

Состоялся релиз сервис пака .NET Framework 3.5SP1 и VS2008 SP1.

Доступны они тут.

The .NET Framework 3.5 SP1 delivers:
* Performance increases between 20-45% for WPF-based applications – without having to change any code
* WCF improvements that give developers more control over the way they access data and services
* Streamlined installation experience for client applications
* Improvements in the area of data platform, such as the ADO.NET Entity Framework, ADO.NET Data Services and support for SQL Server 2008’s new features

Как сделать чтоб WPF Popup был не поверх всех окон (или Win32 API живет до сих пор)

Уже несколько раз подряд за последние дни упираюсь в “пределы” WPF. Причём задачи были отнюдь не экзотические.

Класс Popup генерирует окно, которое располагается поверх всех окон в системе. Если вы хотите изменить это вам поможет только Win32 API:

[DllImport(“user32”, EntryPoint = “SetWindowPos”)]

private static extern int SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int cx, int cy, UInt32 wFlags);

 

const UInt32 SWP_NOSIZE = 0x0001;

const UInt32 SWP_NOMOVE = 0x0002;

const UInt32 SWP_NOACTIVATE = 0x0010;

static readonly IntPtr HWND_BOTTOM = new IntPtr(1);

static readonly IntPtr HWND_TOP = new IntPtr(0);

 

public static void Popup_SetZOrderTop(Popup pop)

{

IntPtr hwnd = ((HwndSource)PresentationSource.FromVisual(pop.Child)).Handle;

SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);

}

 

С помощью этой функции также можно регулировать какое из окон находиться наверху в данный момент.

Получение текущих координат мыши в WPF возможно только с указанием контрола, относительно которого вам нужны эти координаты. А что делать если этот самый контрол нужно двигать?

public struct POINT

{

public int x;

public int y;

};

 

[DllImport(“user32.dll”)]

static extern bool GetCursorPos(out POINT point);

Еще пара полезных функций (поиск окна и получение его положения):

[DllImport(“user32.dll”, SetLastError = true)]

static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

 

[DllImport(“user32.dll”)]

static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

 

public struct RECT

{

public int left;

public int top;

public int right;

public int bottom;

};

Вышла бета Service Pack 1 к .NET 3.5 и Visual Studio 2008

Вышла бета .NET 3.5 Service Pack 1 и Visual Studio 2008, скачать можно тут.

О нововведениях можно почитать тут. Обещаться большой прирост скорости холодной загрузки приложений, а также общей скорости работы WPF, рендеринга текста и битмап-эффектов. Также интересна прямая поддержка DirectX и шейдерных эффектов под WPF. Причём воспользоваться этими эффектами будет легко. Например, код

добавит под кнопку аппаратную тень:

Еще одна новая возможность заслуживает особого внимания – New .NET Framework Client Profile Setup Package. Это возможность создать компактный дистрибутив для машин, на которых не установлен .Net Framework, в котором будут содержаться только нужные части фреймворка:

Также много чего нового для удобства разработки веб приложений и работы с данными (ADO.NEТ Entity framework и ADO.NET Data Services).

Обещано, что это последняя бета и релиз совсем скоро.

Возможности биндинга в XAMLе

А знаете ли Вы, что в XAML можно биндинг описать вот так:

<Border.Background>

<Binding Path=Background>

<Binding.RelativeSource>

<RelativeSource Mode=FindAncestor AncestorType={x:Type ListBoxItem} AncestorLevel=1/>

</Binding.RelativeSource>

</Binding>

</Border.Background>

То есть можно связать свойство элемента с его родителем-контейнером. Этот биндинг очень удобно использовать при написании всяких ControlTemplate. В данном примере приведен кусок из шаблона элемента листбокса, который содержит в себе некий элемент оформления Border. Так вот цвет заливки этой рамки на элементе можно привязать к цвету самого элемента. Удобно.

Хорошая книжка по WPF

Хочу порекомендовать хорошую книжку по WPF, Pro WPF in C# 2008, которую можно скачать с pdfchm.com. Достаточно сказать, что книжка объемом более тысячи страниц и освещает много аспектов, опущенных в аналогичных изданиях.

Хорошая книжка по WPF

Напоминаю, что на вышеуказанном сайте с книжками надо регистрироваться.

Перевод XAML в HTML и как это можно использовать

Если ввести в гугле XAML to HTML то выпадет ссылка на програмку конвертации с исходниками. Конечно возможности этой конвертации ограничены, и не потому что утилита предназначена лишь для описания самого подхода к подобной конвертации, а потому что возможности XAML сильно шире возможностей HTML.

Можно придумать много полезных применений этой утилитки, но я использовал ее для совсем банальной вещи. А именно, я отказался от использования плагина для подсветки синтаксиса в своем блоге, а просто копирую код из студии, нажимаю одну кнопку и получаю html код, который можно вставить в блог. При этом все цвета, шрифты и отступы будут сохранены.

Например:

  /// <summary>

  /// Interaction logic for Window1.xaml

  /// </summary>

 

  public partial class Window1 : System.Windows.Window

  {

 

    public Window1()

    {

      InitializeComponent();

    }

Для реализации этого я всего лишь слегка доработал утилитку, добавив RichTextBox, содержимое которого переводится в XAML :

 string os = XamlWriter.Save(InputText.Document);

 

Об классах XamlReader/XamlWriter я писал немного тут, а таже на сайте готдотнет есть моя статейка на эту тему.

Итого получаем конвертацию содержимого RichTextBox прямо в HTML:

Xaml2Html

А еще можно обратно ковертировать HTML в XAML, и использовать в своих программах.

PerfectPhotos – обработка фотографий на WPF

Хочу представить Вам один из моих последних проектов – программу для обработки фотографий PerfectPhotos. Программа содержит большое количество средств для комплексного улучшения изображений и призвана избавить фотографа от необходимости муторной работы с фотошопом там где это возможно. Более подробное описание возможностей можно найти на сайте.

 

Отмечу лишь, что вся обработка ведется с 16-битным цветом (16 бит на канал).

С версии 1.0.1.96 программа поддерживает напрямую формат цифровых зеркальных камер Canon (.cr2), и с успехом может быть использована в качестве raw-конвертора.

Программа написана на WPF (.Net 3.0) и потому ее интерфейс отличается в лучшую сторону от конкурентов.

.Net 3.5 Roadmap: Улучшения WPF

Scott Guthrie в своем блоге написал о доработках WPF, которые будут реализованы в ближайшем будущем:

Наконец то в WPF будут добавлены контролы для выбора даты и календарь, а также Риббон и DataGrid.

Later this year we are also planning to release a number of new controls for WPF. Included in the list we are working on are DataGrid, Ribbon, and Calendar/DatePicker controls.

Также будут сделана оптимизация BitmapEffects на уровне железа.

Но больше всего меня интересует новый класс WriteableBitmap:

We’ll be including a new WriteableBitmap API that enables real-time bitmap updates from a software surface. We’ll also be adding support for a powerful new effects API that enables you to build richer graphics scenarios.

Пока рано говорить о том, что он может дать.

Полезный Xaml

Все таки Xaml – это полезная вещь. Я написал коротенькую функцию, с помощью которой можно задавать содержимое TextBlock’ов с помощью xaml кода. Это нужно, когда содержимое нужно менять походу выполнения программы. Например, написав:

SetInlines(MyCuteTextBlock, "Крутой текст с <Bold>выделениями</Bold>, переносами строк,<LineBreak/><Underline>подчеркиваниями</Underline> и тому подобными стильными вещицами.");

получаем следующий результат:

 

А добиться такой простой записи позволяет простая функция:

using System.IO;
using System.Windows.Markup;
using System.Xml;
//Create inlines from xaml string
private void SetInlines(TextBlock tb, string XamlCode)
{
    string Op = "<TextBlock xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">";
            string Ed = "</TextBlock>";
            StringReader stringReader = new StringReader(Op + XamlCode + Ed);
            XmlReader xmlReader = XmlReader.Create(stringReader);
            TextBlock TempTB = (TextBlock)XamlReader.Load(xmlReader);
            //Lets copy inlines
            tb.Inlines.Clear();
            List<Inline> inls = new List<Inline>(TempTB.Inlines);
            foreach (Inline nl in inls)
                tb.Inlines.Add(nl);
}

Здесь используется класс XamlReader, который позволяет парсить XAML динамически, то есть уже на этапе исполнения программы.