rksoftware

Visual Studio とか C# とかが好きです

Xamarin 入門者ハンズオン (DevDays ハンズオン) を Xamarin.Forms.WPF でやってみた。

■ 初心者向けXamarinハンズオン

Xamarin は非常に入門者にやさしく Japan Xamarin Users Group 主催の「初心者向けXamarinハンズオン」が4~5ヵ月くらいの間隔で行われています。
現在の日本での Xamarin の入り口と言っていいでしょう。

つまり、日本での Xamarin の基本と言える、ということは新しいプラットフォームがあるなら当然このハンズオンに新しいプラットフォームで挑んでみるわけです。

■ ハンズオン資料

前述のイベントにはぜひ参加してもらいたいところですが、残念ながらお時間の都合のつかない方や遠方の方もご安心ください。
資料は今話題の GitHub というサイトで公開されています。

こちらの資料に沿って学べますので独学でも全然 OK です。

■ 完成プロジェクトについて

大変申し訳ないのですが、完成プロジェクトは公開していません。
前述の日本語訳プロジェクトにはライセンスが明示されているのですが、ソースの置かれている本家にぱっと見で見つけられなかったもので。。。

■ 完成

まず最初に完成写真から。

1ページ目
f:id:rksoftware:20180629013423j:plain

2ページ目
f:id:rksoftware:20180629013439j:plain

完全に一致
f:id:rksoftware:20180629013456j:plain

完璧に対応していますね。すばらしい。

■ 制約

見た目は完璧でしたが、動作はまだ不完全です。

・読み上げるボタン
NotImplementedException が発生します。読み上げ機能は、Xamarin.Forms 本体の機能ではな追加のプラグインの導入という形で実現されています。
このプラグインが、WPF に未対応ということですね。それでもビルドはできるようにまでは対応してくれています。ビルドできないと試せないですから、これはありがたいことです。

・ウェブサイトに移動ボタン
押しても何も起きません。中身まではまだ終えていないので何が起きているのかはわかりませんが、未実装ということなのでしょう。
こちらも、それでもビルドはできるようにまでは対応してくれています。ありがたいです。

■ 作業手順

WPF 版の作業手順は単純です。

・通常のハンズオン手順で、Android・iOS・UWP を完成させる

・Xamrin.Forms.WPF でのデスクトップアプリの作り方通りに WPF プロジェクトを追加する

・実行する

たったこれだけの簡単な仕事です。これだけで WPF のデスクトップアプリになってしまいます。すばらしい。

■ ソースコード

特別なものは何もないのであまり意味はありませんが、WPF プロジェクト内のソースコードも記載しておきます。

App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

App.xaml

<Application x:Class="DevDaysSpeakers.WPF.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:DevDaysSpeakers.WPF"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

App.xaml.cs

using System.Windows;

namespace DevDaysSpeakers.WPF
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
    }
}

MainWindow.xaml

<xf:FormsApplicationPage x:Class="DevDaysSpeakers.WPF.MainWindow"
        xmlns:xf="clr-namespace:Xamarin.Forms.Platform.WPF;assembly=Xamarin.Forms.Platform.WPF"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DevDaysSpeakers.WPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        
    </Grid>
</xf:FormsApplicationPage>

MainWindow.xaml.cs

namespace DevDaysSpeakers.WPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Xamarin.Forms.Platform.WPF.FormsApplicationPage
    {
        public MainWindow()
        {
            InitializeComponent();

            Xamarin.Forms.Forms.Init();
            LoadApplication(new DevDaysSpeakers.App());
        }
    }
}

OpenTK.dll.config

<configuration>
  <dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
  <dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
  <dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
  <dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
  <dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
  <dllmap os="linux" dll="libX11" target="libX11.so.6"/>
  <dllmap os="linux" dll="libXi" target="libXi.so.6"/>
  <dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
  <dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
  <dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
  <dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
  <dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
  <dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
  <dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
  <dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
  <dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
  <!-- XQuartz compatibility (X11 on Mac) -->
  <dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
  <dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
  <dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
  <dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
  <dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
  <dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
</configuration>

packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.Azure.Mobile.Client" version="4.0.2" targetFramework="net461" />
  <package id="Microsoft.Azure.Mobile.Client.SQLiteStore" version="4.0.2" targetFramework="net461" />
  <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net461" />
  <package id="OpenTK" version="2.0.0" targetFramework="net461" />
  <package id="OpenTK.GLControl" version="1.1.2349.61993" targetFramework="net461" />
  <package id="SQLitePCLRaw.bundle_green" version="1.1.2" targetFramework="net461" />
  <package id="SQLitePCLRaw.core" version="1.1.2" targetFramework="net461" />
  <package id="SQLitePCLRaw.lib.e_sqlite3.linux" version="1.1.2" targetFramework="net461" />
  <package id="SQLitePCLRaw.lib.e_sqlite3.osx" version="1.1.2" targetFramework="net461" />
  <package id="SQLitePCLRaw.lib.e_sqlite3.v110_xp" version="1.1.2" targetFramework="net461" />
  <package id="SQLitePCLRaw.provider.e_sqlite3.net45" version="1.1.2" targetFramework="net461" />
  <package id="WpfLightToolkit" version="1.0.1" targetFramework="net461" />
  <package id="Xam.Plugins.TextToSpeech" version="4.0.0.7" targetFramework="net461" />
  <package id="Xamarin.Forms" version="3.0.0.561731" targetFramework="net461" />
  <package id="Xamarin.Forms.Platform.WPF" version="3.0.0.561731" targetFramework="net461" />
</packages>

■ もう試せる

いつもやってるハンズオンにも完全に対応いうことで、Xamarin.Forms.WPF が普通にデスクトップアプリ開発に使える期待がまた一つ高まりました。