【Xamarin】【book】「Xamarin エキスパート養成読本」の学習記録(4) [特集3 - 第1章]

下記の「Xamarin エキスパート養成読本」を使った学習記録のページです。
Xamarinエキスパート養成読本 (Software Design plus)
 

 

環境

「Xamarin エキスパート養成読本」は Visual Studio 2015 で記載されているため、私が使用した Visual Studio 2017 とは若干操作手順が異なる。

  • Windows 10
  • Visual Studio 2017

 
 

概要

ページ系コントロールの使用例。
 

ContentPage の使用例

プロジェクト作成

f:id:dnkrnka:20181021155028p:plain:w400
 

使用例

f:id:dnkrnka:20181021154831p:plain:w200
 

実装

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"
             xmlns:local="clr-namespace:ContentPageSample"
             x:Class="ContentPageSample.MainPage">

    <StackLayout Spacing="20" Padding="20" VerticalOptions="Center" Orientation="Vertical">
        <!-- Place new controls here -->
        <Label x:Name="lblMsg" Text="Hello, CrossplatForm development!!" 
           HorizontalOptions="Center"
           VerticalOptions="Center" />
        <Button Text="ABC" x:Name="btnOk"/>
    </StackLayout>

</ContentPage>

 
 
 
 
 

プロジェクト作成

f:id:dnkrnka:20181021234704p:plain
 

使用例

起動時 f:id:dnkrnka:20181021234813p:plain:w200
「GO TO ・・・」ボタン押下後 f:id:dnkrnka:20181021234927p:plain:w200

 

実装

App.xaml

アプリ全体の制御をする。

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="NavigationPageSample.App">
    <Application.Resources>

    </Application.Resources>
</Application>

 

App.xaml.cs

NavigationPage により MainPage を起動させる。

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace NavigationPageSample
{
  public partial class App : Application
  {
    public App()
    {
      InitializeComponent();

      //    MainPage = new MainPage();
      MainPage = new NavigationPage(new MainPage());
    }

    protected override void OnStart()
    {
      // Handle when your app starts
    }

    protected override void OnSleep()
    {
      // Handle when your app sleeps
    }

    protected override void OnResume()
    {
      // Handle when your app resumes
    }
  }
}

 

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"
             xmlns:local="clr-namespace:NavigationPageSample"
             x:Class="NavigationPageSample.MainPage">

    <StackLayout>
        <!-- Place new controls here -->
        <Label Text="Welcome to Xamarin.Forms!" 
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand" />
    </StackLayout>

</ContentPage>

 

MainPage.xaml.cs

アプリ起動時に最初に表示される画面を実装する。

  • 「GO TO NAVIGATION PAGE」ボタンを作成する。
  • 「GO TO・・・」ボタンが押されたら、MessagePage クラスに遷移させる。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace NavigationPageSample
{
  public partial class MainPage : ContentPage
  {
    public MainPage()
    {
      InitializeComponent();
      Button button = new Button
      {
        Text = "Go To Navigation Page",
        HorizontalOptions = LayoutOptions.Center,
        VerticalOptions = LayoutOptions.Center
      };

      button.Clicked += async (sender, args) =>
      {
        await Navigation.PushAsync(new MessagePage());
      };

      Content = button;
    }
  }
}

 

MessagePage.xaml

「GO TO ・・・」ボタン押下後の画面の実装である

  • 文字を 180度回転させて、赤色文字で「Hello, Navigation Page」と表示させている
<?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="NavigationPageSample.MessagePage">
  <ContentPage.Content>
    <Label Text="Hello, Navigation Page"
               VerticalOptions="Center"
               HorizontalTextAlignment="Center"
               Rotation="-180"
               IsVisible="true"
               FontSize="Large"
               FontAttributes="Bold"
               TextColor="Red" />
  </ContentPage.Content>
</ContentPage>

 

MessagePage.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace NavigationPageSample
{
  [XamlCompilation(XamlCompilationOptions.Compile)]
  public partial class MessagePage : ContentPage
  {
    public MessagePage ()
    {
      InitializeComponent ();
    }
  }
}

 
 
 
 

 

TabbedPage の使用例

プロジェクト作成

f:id:dnkrnka:20181104144403p:plain
 

使用例

単に3つのタブを用意するのみである。
もう少し機能を追加したタブの使い方については、こちらを参照。
f:id:dnkrnka:20181104144436p:plain:w200f:id:dnkrnka:20181104145004p:plain:w200f:id:dnkrnka:20181104145233p:plain:w200
 

実装

MainPage.xaml

雛形が ContentPage だったため、TabbedPage に変更した。

<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:TP"
             x:Class="TP.MainPage">

  <TabbedPage.Children>
   <!-- 1つ目のタブ -->
    <ContentPage Title="タイトル1" Padding="30">
      <Label Text="This is page1." />
    </ContentPage>
   <!-- 2つ目のタブ -->
    <ContentPage Title="タイトル2" Padding="30">
      <Label Text="This is page2." />
    </ContentPage>
   <!-- 3つ目のタブ -->
    <ContentPage Title="タイトル3" Padding="30">
      <Label Text="This is page3." />
    </ContentPage>
  </TabbedPage.Children>
</TabbedPage>

 

MainPage.xaml.cs

デフォルト状態では (作成時の都合で) MainPage の基底クラスが ContentPage だったので、TabbedPage に変更した。
その他は変更せず。

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

namespace TP
{
  public partial class MainPage : TabbedPage
  {
    public MainPage()
    {
      InitializeComponent();
    }
  }
}
App.xaml

アプリ全体の制御をする。
デフォルトの状態のまま実装変更なし。

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TP.App">
    <Application.Resources>

    </Application.Resources>
</Application>

 

App.xaml.cs

デフォルトの状態のまま実装変更なし。

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

[assembly: XamlCompilation( XamlCompilationOptions.Compile )]
namespace TP
{
  public partial class App : Application
  {
    public App()
    {
      InitializeComponent();

      MainPage = new MainPage();
    }

    protected override void OnStart()
    {
      // Handle when your app starts
    }

    protected override void OnSleep()
    {
      // Handle when your app sleeps
    }

    protected override void OnResume()
    {
      // Handle when your app resumes
    }
  }
}

 
 
 
 
 
 

CarouselPage の使用例

CarouselPage はスワイプでページの切り替えをする機能を持つ。

プロジェクト作成

f:id:dnkrnka:20181104151315p:plain
 

使用例

初期状態 左へスワイプする スワイプ完了
f:id:dnkrnka:20181104151023p:plain:w200 f:id:dnkrnka:20181104151115p:plain:w200 f:id:dnkrnka:20181104151145p:plain:w200

 

実装

App.xaml

デフォルト設定のまま変更なし。

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CarouselPageSample.App">
    <Application.Resources>

    </Application.Resources>
</Application>

 

MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<CarouselPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:CarouselPageSample"
             x:Class="CarouselPageSample.MainPage">
  <ContentPage Title="Page1" Padding="10,130,10,10">
    <Label Text="Hello, Page1." VerticalOptions="Start" HorizontalOptions="Center"/>
  </ContentPage>
  <ContentPage Title="Page2" Padding="10,130,10,10">
    <Label Text="Hello, Page2." VerticalOptions="Start" HorizontalOptions="Center"/>
  </ContentPage>
  <ContentPage Title="Page3" Padding="10,130,10,10">
    <Label Text="Hello, Page3." VerticalOptions="Start" HorizontalOptions="Center"/>
  </ContentPage>

</CarouselPage>

 

MainPage.xaml.cs

基底クラスを ContentPage から CarouselPage に変更した。

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

namespace CarouselPageSample
{
  public partial class MainPage : CarouselPage
  {
    public MainPage()
    {
      InitializeComponent();
    }
  }
}

 

App.xaml.cs

デフォルト設定のまま変更なし。

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

[assembly: XamlCompilation( XamlCompilationOptions.Compile )]
namespace CarouselPageSample
{
  public partial class App : Application
  {
    public App()
    {
      InitializeComponent();

      MainPage = new MainPage();
    }

    protected override void OnStart()
    {
      // Handle when your app starts
    }

    protected override void OnSleep()
    {
      // Handle when your app sleeps
    }

    protected override void OnResume()
    {
      // Handle when your app resumes
    }
  }
}

 
 
 
 
 
 
 
 
 

MasterDetailPage の使用例

プロジェクトの作成と実装を行う。

Master ページ と Detail ページを格納するためのプロジェクトを作成する

Xamarin.Forms を選択して MDPSample という名称のプロジェクトを作成する。
テンプレートは「Blank」を選択する。
f:id:dnkrnka:20181104152301p:plain:w800
f:id:dnkrnka:20181104152528p:plain:w800
 

Master ページ を作成する

ソリューションエクスプローラで右クリックをして、「追加」「新しい項目」へと進み、次のように Xamarin.Forms で「MasterPage.cs」を追加する。
f:id:dnkrnka:20181104152955p:plain
 
MasterPage.cs を開いて、継承元を ContentPage から MasterDetailPage に変更する。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace MDPSample
{
	public class MasterPage : MasterDetailPage
	{
		public MasterPage ()
		{
		}
	}
}

 

Master ページに表示するメニュを作成する。

Master ページには次の機能を持たせる。

  • メニュは ListView にする
  • Master ページにはメニュを配置する
  • Detail ページに起動時に表示されるトップ画面を作る

 

まずはトップ画面となる TopPage.cs を作成する。

現段階では TopPage.cs の体裁には拘らないので ContentPage でも選択すれば良い。
ソリューションエクスプローラで右クリックをして、「追加」「新しい項目」へと進み、次のように Xamarin.Forms で「TopPage.cs」を追加する。
f:id:dnkrnka:20181104155543p:plain
コードはTextラベルのみである。

TopPage.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace MDPSample
{
	public class TopPage : ContentPage
	{
		public TopPage ()
		{
			Content = new StackLayout {
				Children = {
					new Label { Text = "Welcome to Xamarin.Forms!" }
				}
			};
		}
	}
}

 

次に Master ページの作成をする

前述の通り Master ページでは次の機能を持たせるために MasterPage.cs の MasterPage メソッドを実装する。

  • メニュは ListView にする
  • Master ページにはメニュを配置する
  • Detail ページに起動時に表示されるトップ画面を作る
MasterPage.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace MDPSample
{
  public class MasterPage : MasterDetailPage
  {
    public MasterPage()
    {
      // メニュに表示する文字の配列
      var menu = new[] { "メインページ", "サブページ1", "サブページ2", "サブページ3", };

      // メニュ用の ListView
      ListView listView = new ListView
      {
        ItemsSource = menu, // メニュを追加する
        BackgroundColor = Color.White, // メニュ部分の背景色を白に設定する
      };

      // Masterページ
      Master = new ContentPage
      {
        BackgroundColor = Color.White,
        Padding = new Thickness( 0, 20, 0, 0 ),
        Title = "メニュ", // 必須
        Content = listView
      };

      Detail = new NavigationPage( new TopPage() );
    }
  }
}

 

起動画面の変更

起動画面は TopPage.cs であり、上述の MasterPage.cs から呼び出されるようにしたいので、App.xaml.cs にて次のように実装する。

App.xaml.cs
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

[assembly: XamlCompilation( XamlCompilationOptions.Compile )]
namespace MDPSample
{
  public partial class App : Application
  {
    public App()
    {
      InitializeComponent();

      // MainPage = new MainPage();
      MainPage = new MasterPage();
    }

    protected override void OnStart()
    {
      // Handle when your app starts
    }

    protected override void OnSleep()
    {
      // Handle when your app sleeps
    }

    protected override void OnResume()
    {
      // Handle when your app resumes
    }
  }
}

 

アプリの実行

ここまででビルドをしてアプリを起動すると次のような画面になる。

起動時 左上のメニュボタンクリック時
f:id:dnkrnka:20181104161043p:plain:w200 f:id:dnkrnka:20181104161150p:plain:w200

 

Detail ページの作成

上図の通りメニュには「メインページ」「サブページ1」「サブページ2」「サブページ3」がある。
現在「メインページ」には TopPage.cs を割り当てているので、「サブページ1」「サブページ2」「サブページ3」にもクラスを割り当てる。

「サブページ1」の作成

ソリューションエクスプローラで右クリックをして、「追加」「新しい項目」へと進み、次のように Xamarin.Forms で「SubPage1.cs」を追加する。
SubPage1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace MDPSample
{
  public class SubPage1 : ContentPage
  {
    public SubPage1 ()
    {
      Content = new StackLayout {
        Children = {
          new Label { Text = "SubPage 1" }
        }
      };
    }
  }
}

 
SubPage2.cs や SubPage3.cs も同じ要領で作成する。
SubPage2.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace MDPSample
{
  public class SubPage2 : ContentPage
  {
    public SubPage2 ()
    {
      Content = new StackLayout {
        Children = {
          new Label { Text = "SubPage 2" }
        }
      };
    }
  }
}

 
SubPage3.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace MDPSample
{
  public class SubPage3 : ContentPage
  {
    public SubPage3 ()
    {
      Content = new StackLayout {
        Children = {
          new Label { Text = "SubPage 3" }
        }
      };
    }
  }
}

 

Masterページからサブページを呼び出せるようにする

MasterPage.cs

前述の「 Detail = new NavigationPage( new TopPage() )」以降に次のコードを追加する。

前略
      // メニュ項目のタップ時の処理
      listView.ItemTapped += ( sender, e ) =>
      {
        ContentPage newPage;

        // タップされたメニュ項目を switch で判断する
        switch ( e.Item.ToString() )
        {
          case "メインページ":
            newPage = new TopPage();
            break;
          case "サブページ1":
            newPage = new SubPage1();
            break;
          case "サブページ2":
            newPage = new SubPage2();
            break;
          case "サブページ3":
            newPage = new SubPage3();
            break;
          default:
            newPage = new TopPage();
            break;
        }

        // 選択ページを表示する
        Detail = new NavigationPage( newPage );

        // 選択ページのリセット
        ((ListView)sender).SelectedItem = null;

        // メニュを閉じる
        IsPresented = false;
      };
以下略

 

完成後の動作

起動時 メニュクリック時
f:id:dnkrnka:20181104163618p:plain:w200 f:id:dnkrnka:20181104163534p:plain:w200
メインページ 選択時 サブページ1 選択時 サブページ2 選択時 サブページ3 選択時
f:id:dnkrnka:20181104163818p:plain:w200 f:id:dnkrnka:20181104163134p:plain:w200 f:id:dnkrnka:20181104163156p:plain:w200 f:id:dnkrnka:20181104163215p:plain:w200

 

完成時のプロジェクト構成

f:id:dnkrnka:20181104163922p:plain
 

完成時の実装

App.xaml
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MDPSample.App">
  <Application.Resources>

  </Application.Resources>
</Application>

 

App.xaml.cs
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

[assembly: XamlCompilation( XamlCompilationOptions.Compile )]
namespace MDPSample
{
  public partial class App : Application
  {
    public App()
    {
      InitializeComponent();

      // MainPage = new MainPage();
      MainPage = new MasterPage();
    }

    protected override void OnStart()
    {
      // Handle when your app starts
    }

    protected override void OnSleep()
    {
      // Handle when your app sleeps
    }

    protected override void OnResume()
    {
      // Handle when your app resumes
    }
  }
}

 

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"
             xmlns:local="clr-namespace:MDPSample"
             x:Class="MDPSample.MainPage">

  <StackLayout>
    <!-- Place new controls here -->
    <Label Text="Welcome to Xamarin.Forms!" 
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand" />
  </StackLayout>

</ContentPage>

 

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

namespace MDPSample
{
  public partial class MainPage : ContentPage
  {
    public MainPage()
    {
      InitializeComponent();
    }
  }
}

 

SubPage1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace MDPSample
{
  public class SubPage1 : ContentPage
  {
    public SubPage1 ()
    {
      Content = new StackLayout {
        Children = {
          new Label { Text = "SubPage 1" }
        }
      };
    }
  }
}

 

SubPage2.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace MDPSample
{
  public class SubPage2 : ContentPage
  {
    public SubPage2 ()
    {
      Content = new StackLayout {
        Children = {
          new Label { Text = "SubPage 2" }
        }
      };
    }
  }
}

 

SubPage3.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace MDPSample
{
  public class SubPage3 : ContentPage
  {
    public SubPage3 ()
    {
      Content = new StackLayout {
        Children = {
          new Label { Text = "SubPage 3" }
        }
      };
    }
  }
}

 

TopPage.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace MDPSample
{
  public class TopPage : ContentPage
  {
    public TopPage()
    {
      Content = new StackLayout
      {
        Children = {
          new Label { Text = "Welcome to Xamarin.Forms!" }
        }
      };
    }
  }
}