Один контрол на всех, и все на одного: WPF, Silverlight 4-5, WinPhone 7-8, Windows Store App (x86, x64, ARM)
Сразу дискламер — это не Розеттский камень, а лишь хитрость, которая поможет, если у вас есть UserControl, почти идентичный для всех платформ.
Бонус — видео процесса разработки в конце статьи — статья простая и короткая, а видео 8 минут отличной музыки. Не у всех есть Windows8, многим наверное будет просто любопытно увидеть процесс в W8 + VS2012, поэтому заморочался.
Нам подарили Portable Library — отличная штука, сразу для всех платформ. Но, есть и ложка дёгтя — почти ничего, кроме числомолотилки и бизнес-процессов с этим не сварить, поддерживаемые неймспейсы подвели.
Эта штука не только не знает что такое XAML, но не знает даже что такое Point! Куда уж проще, две координаты, X и Y — но это проблема, и предмет отдельного обсуждения с лучами ненависти к индусам и бардаку архитекторов.
Итак, мое первое знакомство с Portable Library случилось не лучшим образом — оно напомнило мне случай, когда девушка поднялась ко мне в диджейку и передразнила Аллегрову: «Я ждала тебя, так ждала, ты был мечтою моей фрустральною!» (Но там боссы корпоратива заказывали музыку..)
Но я придумал, как побороть проблему с PL, которая назревала у моей будущей статьи про HSL Color Dialog, и эта статья — приставка к следующей статье, и туториал.
Сразу оговорюсь, не во всех случаях поможет, в WinRT например нет Label, но везде есть TextBlock, «специфику платформ» придется соблюдать.
Краткое описание видео:
1. Создаем солюшн, и в нем проект WPF UserControl. Это будет наша песочница, именно в ней мы будем создавать и редактировать будущий универсальный контрол(ы). Сам по себе этот проект в продакшне не нужен, так-что лично я назвал его Sandbox и забил.
1а. Нас интересует только голый XAML. Удаляем из XAML наименование класса, удаляем сам файл .cs.
1б. Редактируем XAML, и он самое важное, это рабочий файл, годный для работы GUI-дизайнерам, в Бленде например.
2. Создаем проект Portable Library, выбираем из диалога нужные версии всего, что нам надо.
2а. В проект PL добавить XAML с контролом из песочницы. Важно: добавить как Link на файл. Иначе все GUI-изменения в проекте песочницы над контролом придется руками перетаскивать каждый раз.
2б. Добавленный линк на файл сделать Embedded Resource.
2в. Embedded Resource достается и передается в райнтайме так:
public class Class1
{
public Stream GetXaml()
{
string[] names = this.GetType().Assembly.GetManifestResourceNames();
Stream s = this.GetType().Assembly.GetManifestResourceStream(names[0]);
return s;
}
}
Важно: PL ничерта не знает, что на самом деле передает XAML, а принимающие приложения не знают достоверно, что это валидный XAML, так-что в продакшне важно обложиться проверками! Я их далее опустил, ради простоты кода.
3. Создаем любой GUI-проект из семейства WPF-родственничков. Единственная киллер-фича в этой многоплатформенности — парсинг XAML в райнтайме. Пользуемся ей примерно так:
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
Class1 class1 = new Class1();
DependencyObject importedXaml;
using (Stream stream = class1.GetXaml())
{
importedXaml = XamlReader.Load(stream) as DependencyObject;
stream.Close();
}
UserControl control = importedXaml as UserControl;
rootGrid.Children.Add(control);
}
Еще раз напоминаю о проверках.
В данном случае, наша PL-библиотека выступила лишь как прокси, передающая контрол любой платформе WPF-семейства, воспользовавшись своей уникальной способностью в одиночку быть подргруженной любым из них.
И тем, что XAML (в основном) у всех одинаковый до последней буквы.
Да, костыль! Но и пользы в разработке хватает.
Далее, под каждую платформу уже можно при необходимости завести Dictionary с описанием стилей для элементов.
Видео ниже охватывает все платформы, но порезано и ускорено (оригинальный скринкаст был ~45 минут). Vimeo дал гароздо более четкую картинку на том-же разрешении, что Youtube. Если Vimeo — это косяк, я могу на Youtube дубль сделать.
Всем отличных выходных!
Автор: Lincoln6Echo