A certain engineer "COMPLEX"

Xamarinメモ その18 Xamarin.Forms.ThemesをPrism.Unity.Formsと併用する場合の注意

前回はNavigationPageとTabbedPageの組み合わせ問題を解決しました。

Problem


お詫び

Xamarin.Formsヒトバシラー様より、UWPが動かない原因を指摘していただきました。
謹んで記事を訂正させていただきます。

Xamarin.Formsヒトバシラー (@ticktackmobile)さんの最新ツイート。ソフトウェア開発者。C#、WPF、Xamarin(Forms)とか。呉鎮守府の潮提督。Xamarin.Forms製AED検索アプ...

Evolve 2016でXamarin.FormsにTheme機能を追加することが発表されましたが、そのマイルストーン?として日本時間5/5の夜にXamarin.Forms.ThemesのNuGetパッケージが公開されました。
まだ、NuGetのページもありませんが、Nuget PackageManagerから入手可能です。

2016/05/06 1:57 訂正

Build native UIs for iOS, Android, and Windows Phone from a single, shared C# codebase

からの抜粋です。
注意するのは、x:Classの指定です。ここは、PCLのApp.csと同じになるよう修正してください。
Application.Resources内部は、NuGetで適用した、または使用した方を残してください。

補足ですが、App.xamlのカスタムツールとビルドアクションはそのままで結構です。
また、カスタムツールがMSBuild:UpdateDesignTimeXaml、ビルドアクションが埋め込みリソースです。
ビルドアクションがPageだと動きません、というかビルドが通りません。

App.cs


この時点で、App.xamlとApp.csが結びつきましたが、このままではビルドが通りません。
修正は簡単です。


public partial class App : Application

partial属性を付与するだけです。
ちなみに、App.csをApp.xaml.csにする必要はないです。サンプルはそうですか不要です。

おまじない


公式ページにもありましたが、必要なアセンブリがロードされないことがあるようです。

Android、iOSごとに対応があります。
必要に応じて適用をお願いします。

App.cs (Prism.Forms.Unity使う人向け)


この時点で、無事にThemeが適用されるはずですが、Prism.Unity.Forms使いはそうも行きません。
App.csにさらに修正が必要です。
通常、Appコンストラクタ内で、UnityBootstrapperの派生クラスのインスタンスの生成、およびRunメソッドのコールをしていますが、このままでは、Themeが適用されません。
だいたい、下記のような感じだと思います。


public App()
{
var bootstrapper = new Bootstrapper();
bootstrapper.Run(this);
}

これを、


public App()
{
var bootstrapper = new Bootstrapper();
bootstrapper.Run(this);

this.InitializeComponent();
}

に修正してください。
InitializeComponentが先に来ると、フリーズします。具体的には、CreateMainPageメソッドでMainPageのResolveで止まります。
このあたり、ひょっとしたら今後の更新で対応されるかもしれませんが、今はこれで動くはずです。

実行してみる


iOS

サンプル

サンプル

一部Themeが適用されていないような気がしますが、別途修正が必要?

Android

サンプル

サンプル

UWP

Prism.Unity.Forms環境下では実行できませんでした。というか動かなくなります。もっと検証が必要かも。

簡単なサンプルを作って、UWPを動かしましたがダメです。



Xamarin.Forms.Xaml.XamlParseException: Position 19:16. No Property of name StyleClass found
at Xamarin.Forms.Xaml.ApplyPropertiesVisitor.SetPropertyValue(Object xamlelement, XmlName propertyName, Object value, BindableObject rootElement, INode node, HydratationContext context, IXmlLineInfo lineInfo)
at Xamarin.Forms.Xaml.ApplyPropertiesVisitor.Visit(ValueNode node, INode parentNode)
at Xamarin.Forms.Xaml.ValueNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
at Xamarin.Forms.Xaml.Eleme



at Xamarin.Forms.Xaml.ApplyPropertiesVisitor.SetPropertyValue(Object xamlelement, XmlName propertyName, Object value, BindableObject rootElement, INode node, HydratationContext context, IXmlLineInfo lineInfo)
at Xamarin.Forms.Xaml.ApplyPropertiesVisitor.Visit(ValueNode node, INode parentNode)
at Xamarin.Forms.Xaml.ValueNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
at Xamarin.Forms.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
at Xamarin.Forms.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
at Xamarin.Forms.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
at Xamarin.Forms.Xaml.RootNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
at Xamarin.Forms.Xaml.XamlLoader.Load(BindableObject view, String xaml)
at Xamarin.Forms.Xaml.XamlLoader.Load(BindableObject view, Type callingType)
at Xamarin.Forms.Xaml.Extensions.LoadFromXaml[TView](TView view, Type callingType)
at XFApp1.BasicPage.InitializeComponent()
at XFApp1.BasicPage..ctor()
at XFApp1.App..ctor()
at XFApp1.UWP.MainPage..ctor()
at XFApp1.UWP.XFApp1_UWP_XamlTypeInfo.XamlTypeInfoProvider.Activate_4_MainPage()
at XFApp1.UWP.XFApp1_UWP_XamlTypeInfo.XamlUserType.ActivateInstance()

こんな感じのメッセージとスタックトレースを吐いて落ちます。
StyleClassが無い、という例外です。PCLに存在していても、実行するプラットフォームに突入した時点で存在しない?
哀れUWP....

なので、簡単なサンプルを作りました。
UWPプロジェクトは以下のApp.xaml内部のRequestedThemeを削除して、Xamarin.Forms.Theme.Lightを適用した結果がこちら。

サンプル

サンプル

Conclusion


早速、レビューしましたが、プレリリースだけあって、不安定極まりないです。
UWPが見捨てられたのは、どういうわけなのか....時間が無かっただけ、と思いたい。

コメントを残す

メールアドレスが公開されることはありません。

%d人のブロガーが「いいね」をつけました。