WPF и жизненный цикл приложений Xamarin.Forms

Xamarin.Forms принимает много рекомендаций по проектированию из платформ на основе XAML, которые появились до него, особенно WPF. Тем не менее, в других способах он значительно отклоняется, что может быть липкой точкой для людей, пытающихся перейти. Этот документ пытается определить некоторые из этих проблем и предоставить рекомендации, где это возможно, чтобы мостить знания WPF к Xamarin.Forms.

Жизненный цикл приложения

Жизненный цикл приложения между WPF и Xamarin.Forms аналогичен. Оба запускают внешний (платформенный) код и запускают пользовательский интерфейс с помощью вызова метода. Разница заключается в том, что Xamarin.Forms всегда запускается в сборке для конкретной платформы, которая затем инициализирует и создает пользовательский интерфейс для приложения.

WPF

  • Main method > App > MainWindow

Примечание.

Метод Main по умолчанию создается автоматически и не отображается в коде.

Xamarin.Forms

  • iOSMain method > AppDelegate > App > ContentPage
  • AndroidMainActivity > App > ContentPage
  • UWPMain method > App(UWP) > MainPage(UWP) > App > ContentPage

Класс приложений

Как WPF, так и Xamarin.Forms имеют Application класс, который создается как одноэлементный. В большинстве случаев приложения будут производными от этого класса для предоставления пользовательского приложения, хотя это не является строго обязательным в WPF. Оба предоставляют Application.Current свойство для поиска созданного одноэлементного элемента.

Глобальные свойства и сохраняемость

В WPF и Xamarin.Forms есть Application.Properties словарь, в котором можно хранить глобальные объекты уровня приложений, доступные в любом месте приложения. Ключевое различие заключается в том, что Xamarin.Forms будет сохранять любые примитивные типы, хранящиеся в коллекции при приостановке приложения, и перезагрузить их при повторном запуске. WPF не поддерживает это поведение автоматически. Вместо этого большинство разработчиков полагаются на изолированное хранилище или использовали встроенную Settings поддержку.

Определение страниц и визуального дерева

WPF использует в Window качестве корневого элемента для любого визуального элемента верхнего уровня. Это определяет HWND в мире Windows для отображения информации. Вы можете одновременно создавать и отображать столько окон, сколько вам нравится в WPF.

В Xamarin.Forms визуальный элемент верхнего уровня всегда определяется платформой , например в iOS, это .UIWindow Xamarin.Forms отображает его содержимое в эти собственные представления платформы с помощью Page класса. Каждая Page из них в Xamarin.Forms представляет собой уникальную "страницу" в приложении, где одновременно отображается только одна.

Как WPFs, так и Xamarin.Forms WindowPage включают Title свойство, влияющее на отображаемое название, и есть Icon свойство для отображения определенного значка страницы (обратите внимание , что название и значок не всегда отображаются в Xamarin.Forms). Кроме того, можно изменить общие визуальные свойства как в цвете фона, так и в изображении.

Технически можно отрисовывать два отдельных представления платформы (например, определять два UIWindow объекта и иметь второй отрисовки во внешний дисплей или AirPlay), для этого требуется код, зависящий от платформы, и не является непосредственно поддерживаемой функцией самого Xamarin.Forms.

Представления

Визуальная иерархия для обеих платформ аналогична. WPF немного глубже из-за поддержки документов WYSIWYG.

WPF

DependencyObject - base class for all bindable things
   Visual - rendering mechanics
      UIElement - common events + interactions
         FrameworkElement - adds layout
            Shape - 2D graphics
            Control - interactive controls

Xamarin.Forms

BindableObject - base class for all bindable things
   Element - basic parent/child support + resources + effects
      VisualElement - adds visual rendering properties (color, fonts, transforms, etc.)
         View - layout + gesture support

Жизненный цикл представления

Xamarin.Forms в основном ориентирован на мобильные сценарии. Таким образом, приложения активируются, приостановлены и повторно активируютсяпри взаимодействии с ними пользователем. Это аналогично щелчку в Window приложении WPF, и есть набор методов и соответствующих событий, которые можно переопределить или подключить к этому поведению.

Характер использования Метод WPF Метод Xamarin.Forms
Начальная активация ctor + Window.OnLoaded ctor + Page.OnStart
Показано Window.IsVisibleChanged Page.Appearing
Скрыт Window.IsVisibleChanged Page.Disappearing
Приостановка и потеря фокуса Window.OnDeactivated Page.OnSleep
Активация или фокус Window.OnActivated Page.OnResume
Закрытые Window.OnClosing + Window.OnClosed Н/Д

Обе поддерживают скрытие и отображение дочерних элементов управления, а также в WPF это три состояния ( IsVisible видимое, скрытое и свернутое). В Xamarin.Forms он просто видим или скрыт через IsVisible свойство.

Макет

Макет страницы выполняется в одном и том же 2-проходном режиме (мера/упорядочение), которое происходит в WPF. Вы можете подключиться к макету страницы, переопределив следующие методы в классе Xamarin.Forms Page :

Способ Характер использования
OnChildMeasureInvalidated Предпочтительный размер дочернего элемента изменился.
OnSizeAllocated Страница была назначена ширину или высоту.
Событие LayoutChanged Изменен макет или размер страницы.

Нет глобального события макета, которое называется сегодня, и не существует глобального CompositionTarget.Rendering события, как найдено в WPF.

Общие свойства макета

WPF и Xamarin.Forms поддерживают Margin интервалы между элементами и Padding управлять интервалами внутри элемента. Кроме того, большинство представлений макета Xamarin.Forms имеют свойства для управления интервалами (например, строка или столбец).

Кроме того, большинство элементов имеют свойства для влияния на то, как они размещаются в родительском контейнере:

WPF Xamarin.Forms Характер использования
ГоризонтальноеВыравнивание HorizontalOptions Параметры слева,центра/справа/растяжения
VerticalAlignment VerticalOptions Параметры top/Center/Bottom/Stretch

Примечание.

Фактическое толкование этих свойств зависит от родительского контейнера.

Представления макета

WPF и Xamarin.Forms используют элементы управления макетом для размещения дочерних элементов. В большинстве случаев они очень близки друг к другу с точки зрения функциональности.

WPF Xamarin.Forms Стиль макета
StackPanel StackLayout Слева направо или бесконечный стек сверху вниз
Сетка Сетка Табличный формат (строки и столбцы)
DockPanel Н/Д Закрепление к краям окна
Холст AbsoluteLayout Положение пикселей и координат
WrapPanel Н/Д Стек упаковки
Н/Д RelativeLayout Относительное расположение на основе правил

Примечание.

Xamarin.Forms не поддерживает GridSplitter.

Обе платформы используют присоединенные свойства для точной настройки дочерних элементов.

Отрисовка

Механика отрисовки для WPF и Xamarin.Forms радикально отличается. В WPF элементы управления, которые вы создаете непосредственно отрисовку содержимого в пикселях на экране. WPF поддерживает два графа объектов (деревья) для представления этого. Логическое дерево представляет элементы управления, определенные в коде или XAML, и визуальное дерево представляет фактическую отрисовку, которая выполняется непосредственно визуальным элементом (с помощью метода виртуальной рисования), или с помощью xaml-определенияControlTemplate, который можно заменить или настроить. Как правило, визуальное дерево сложнее, так как оно включает такие вещи, как границы вокруг элементов управления, метки для неявного содержимого и т. д. WPF включает набор API (LogicalTreeHelper и VisualTreeHelper) для изучения этих двух графов объектов.

В Xamarin.Forms элементы управления, которые определяются в ней Page , являются просто простыми объектами данных. Они похожи на представление логического дерева, но никогда не отображают содержимое самостоятельно. Вместо этого они представляют собой модель данных, которая влияет на отрисовку элементов. Фактический отрисовка выполняется отдельным набором визуальных отрисовщиков , которые сопоставляются с каждым типом элемента управления. Эти отрисовщики регистрируются в каждом из проектов для конкретной платформы сборками Xamarin.Forms. Здесь можно просмотреть список. Помимо замены или расширения отрисовщика, Xamarin.Forms также поддерживает эффекты, которые можно использовать для влияния на собственную отрисовку на основе каждой платформы .

Логическое или визуальное дерево

Нет доступного API для обхода логического дерева в Xamarin.Forms, но вы можете использовать Рефлексия для получения той же информации. Например, вот метод, который может перечислять логические дочерние элементы с отражением.

Графика

Xamarin.Forms включает в себя графическую систему для рисования примитивов, которая называется фигурами. Дополнительные сведения о фигурах см. в разделе "Фигуры Xamarin.Forms". Кроме того, можно включить сторонние библиотеки, такие как SkiaSharp , чтобы получить кроссплатформенный трехмерный рисунок.

Ресурсы

WPF и Xamarin.Forms имеют концепцию ресурсов и словарей ресурсов. Вы можете поместить любой тип объекта в ResourceDictionary ключ, а затем найти его для {StaticResource} вещей, которые не изменятся, или {DynamicResource} для вещей, которые могут измениться в словаре во время выполнения. Использование и механика совпадают с одним отличием: Xamarin.Forms требует, чтобы Resources вы определили ResourceDictionary назначение свойству, а WPF предварительно создает один и назначает его для вас.

Например, см. определение ниже.

WPF

<Window.Resources>
   <Color x:Key="redColor">#ff0000</Color>
   ...
</Window.Resources>

Xamarin.Forms

<ContentPage.Resources>
   <ResourceDictionary>
      <Color x:Key="redColor">#ff0000</Color>
      ...
   </ResourceDictionary>
</ContentPage.Resources>

Если вы не определяете ошибку ResourceDictionaryсреды выполнения, создается ошибка среды выполнения.

Стили

Стили также полностью поддерживаются в Xamarin.Forms и могут использоваться для темы элементов Xamarin.Forms, составляющих пользовательский интерфейс. Они поддерживают триггеры (свойства, события и данные), наследование и BasedOnпоиск ресурсов для значений. Стили применяются либо к элементам явным образом через Style свойство, либо неявно, не предоставляя ключ ресурса, как и WPF.

Стили устройства

WPF имеет набор предопределенных свойств (хранящихся в виде статических значений в наборе статических классов, таких как SystemColors) которые диктуют системные цвета, шрифты и метрики в виде значений и ключей ресурсов. Xamarin.Forms аналогичен, но определяет набор стилей устройств для представления одинаковых элементов. Эти стили предоставляются платформой и задаются значениями в зависимости от среды выполнения (например, специальных возможностей).

WPF

<Label Text="Title" Foreground="{DynamicResource {x:Static SystemColors.DesktopBrushKey}}" />

Xamarin.Forms

<Label Text="Title" Style="{DynamicResource TitleStyle}" />