放浪軍師のXamarin.Formsアプリ開発局

Xamarin.Forms+Prism+ReactivePropertyで素人がAndroidやUWPのアプリを右往左往しながら開発している様を発信していきます。性質上間違いも多いのでご注意ください。

まずは初期コードを確認しよう

放浪軍師のXamarin.Formsによるアプリ開発

オリンピックで盛り上がっちゃってしばらくサボってました。ごめんなさい。

 

今回は初期コードの確認を行っていきます。

まず、初めて訪問された方は以下をお読みください。

www.gunshi.info

何があるか確認

環境構築時に作成したプロジェクトでプログラミングしていこうと思っていますので、まずは既に存在するファイル構成を確認します。

f:id:roamschemer:20180228001102j:plain

ソリューションの下にHelloXamarin,HelloXamarin.Android,HelloXamarin.UWPが存在しています。

多分HelloXamarinは共通項目、.Androidや.UWPには電話機能やカメラ機能など、其々独自の記述をする際に扱う場所だと推測されますが、今回はとりあえずHelloXamarinだけ確認してみます。

 

HelloXamarinを開くと、このようになっています。

 f:id:roamschemer:20180228000851j:plain

MVVMの記事で確認したViewModelsやViewsといったフォルダが存在していますね。ただ、Modelに関するフォルダが見当たりません。自作しろと言うことでしょうか?また、フォルダ外にもファイルが存在しています。Appと付いているので、起点になるファイルでしょうか?

 

そして、それらの中には.xamlと.csが存在しています。

確認してみると、.xamlはその名の通りxamlの記述があり、.csにはc#の記述がありました。

ちょっと長いですが、大事だと思うので一つずつ確認していきます。

 

App.xmal

<?xml version="1.0" encoding="utf-8" ?>
<prism:PrismApplication xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.DryIoc;assembly=Prism.DryIoc.Forms"
             x:Class="HelloXamarin.App">
	<Application.Resources>

		<!-- Application resource dictionary -->

	</Application.Resources>
</prism:PrismApplication>

XMLとほぼ同じ記述方式で書かれていますね。XMLは仕事で関わる事が多いので抵抗はないです。ただ、何が書かれているかは今のところよくわかりません。

 

App.cs

using Prism;
using Prism.Ioc;
using HelloXamarin.ViewModels;
using HelloXamarin.Views;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Prism.DryIoc;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace HelloXamarin
{
    public partial class App : PrismApplication
    {
        /* 
         * The Xamarin Forms XAML Previewer in Visual Studio uses System.Activator.CreateInstance.
         * This imposes a limitation in which the App class must have a default constructor. 
         * App(IPlatformInitializer initializer = null) cannot be handled by the Activator.
         */
        public App() : this(null) { }

        public App(IPlatformInitializer initializer) : base(initializer) { }

        protected override async void OnInitialized()
        {
            InitializeComponent();

            await NavigationService.NavigateAsync("NavigationPage/MainPage");
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<NavigationPage>();
            containerRegistry.RegisterForNavigation<MainPage>();
        }
    }
}

 おー!わけわからん!ただなにやらMainPageという記述があるので、そっちを起点に始めろよ的な?こと書いてんじゃね?適当ですけど。

 

Views\MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloXamarin.Views.MainPage"
             Title="{Binding Title}">

    <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
        <Label Text="Welcome to Xamarin Forms and Prism!" />
    </StackLayout>

</ContentPage>

Viewsフォルダ内なので、画面構成に直接関わる記述だと思われます。真ん中あたりの<Label Text="Welcome to Xamarin Forms and Prism!" />

という記述が、初期状態で生成された画面に表示されていた文字で、これを変更すればその文字を変更できるようです。

<StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">

の部分は画面のレイアウトですね。真ん中あたりに前述の文字を表示しろよとか書いてあるんだと思います。

あと気になるのは

Title="{Binding Title}"

の部分です。前回の記事で確認しましたが、MVVMではViewとViewModelはデータバインディングのみで繋ぎ、ソフトウェアの挙動は、ModelとViewModelとのやり取りだけで完結させるとありました。多分それを再現するための記述です。

 

www.gunshi.info


 

Views\MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace HelloXamarin.Views
{
	public partial class MainPage : ContentPage
	{
		public MainPage ()
		{
			InitializeComponent ();
		}
	}
}

こちらも同じく画面構成用のコードだと思いますが、ほぼ何も書いていないに等しいですね。おそらくC#のコードで画面を構成する場合はこっちに記述するんじゃないでしょうか?調べてみたところxamlではループ処理なんかが記述できないようなので、ちょっと柔軟な画面を作りたい場合は限界が来ると思いますので、その際はこっちに記述するのかな?

 

ViewModels/MainPageViewModel.cs

using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HelloXamarin.ViewModels
{
    public class MainPageViewModel : ViewModelBase
    {
        public MainPageViewModel(INavigationService navigationService) 
            : base (navigationService)
        {
            Title = "Main Page";
        }
    }
}

ViewModelsには何故か2つのファイルが存在します。どちらもC#のコードですね。

このMainPageViewModel.csには、

Title = "Main Page";

という記述があり、初期状態で生成された画面にも同様のタイトルがついていました。ここを変更すると、タイトルも変更できます。

f:id:roamschemer:20180228003308p:plain

Views\MainPage.xamlにあったTitle="{Binding Title}"はこれとデータバインディングで繋がっているという訳ですね。なるほど。

 

ViewModels/ViewModelBase.cs

using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Text;

namespace HelloXamarin.ViewModels
{
    public class ViewModelBase : BindableBase, INavigationAware, IDestructible
    {
        protected INavigationService NavigationService { get; private set; }

        private string _title;
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        public ViewModelBase(INavigationService navigationService)
        {
            NavigationService = navigationService;
        }

        public virtual void OnNavigatedFrom(NavigationParameters parameters)
        {
            
        }

        public virtual void OnNavigatedTo(NavigationParameters parameters)
        {
            
        }

        public virtual void OnNavigatingTo(NavigationParameters parameters)
        {
            
        }

        public virtual void Destroy()
        {
            
        }
    }
}

ViewModelsフォルダにあるもう一つのファイルです。先ほどのTitleについて、プロパティが宣言されているみたいです。…ということは、このファイルは、ViewModelのプロパティを宣言する場所???ほかには、画面を開いたときや閉じたときの挙動に関するコードっぽい記述がありますね。

 

 

…とまぁこんなところですか。わけわからない部分も多々ありますが、こっからはとりあえずやってみるっきゃないですね。

ただ、今確認したPrismによる初期生成コードの内容ですが、どのブログを巡っても微妙に書いてあることが違うんですよね。俺が所有している参考本ともやっぱり違います。多分Prismのバージョンが新しくなった為だと思いますがうーん…厳しい。

 

ま、なんとかなるさー!次いってみましょ!