記事一覧

MasterDetailPageの設定方法 | Xamarin.Forms


今回は親子関係のページを作成する方法をご紹介いたします。
メニューのページをMasterPage、そのメニューから遷移するページをDetailPage、その両者をコントロールするのがMasterDetailPageと呼びます。
よって、MasterDetailPageを構成するには最低3つのContentPageが必要になります。


画面イメージ
iOS9
MasteDetailPage_01.png
Android5
MasterDetailPage_02.jpg




前提条件
・Windows10
・Visual Studio 2015 Community Update3
・Xamarin 4.2.0.719 (NuGet Xamarin.Forms 2.3.2.127)
・macOS Sierra 10.12.1 / Xcode8.1 / Xamarin.iOS 10.2.0.4



1.MasterPageのメニューを作成する

PCLにてMenuPage.cs

/// <summary>
/// 左側のメニューページクラスです。
/// </summary>
public class MenuPage : ContentPage
{
    public ListView Menu { get; set; }

    public MenuPage()
    {
        Icon = "menu.png";
        Title = "Menu";     // Icon を指定しても Title プロパティは必須項目です。
        BackgroundColor = Color.FromHex("dce8ef");

        // ListView 設定
        Menu = new MenuListView();

        var menuLabel = new ContentView
        {
            Padding = new Thickness(10, 36, 0, 5),
            Content = new Label
            {
                TextColor = Color.FromHex("333"),
                Text = "MENU",
                FontSize = 18,
            }
        };

        // タイトルの menuLabel と ListView を並べています。
        var layout = new StackLayout
        {
            Spacing = 0,
            VerticalOptions = LayoutOptions.FillAndExpand
        };
        layout.Children.Add(menuLabel);
        layout.Children.Add(Menu);

        Content = layout;
    }
}

/// <summary>
/// ListView を継承したクラスです。ItemsSource で List<MenuItem>、ItemTemplate で ImageCell を使用しています。
/// </summary>
public class MenuListView : ListView
{
    public MenuListView()
    {
        //MenuListDataクラスをインスタンス化してItemsSource として指定します。
        List<MenuItem> data = new MenuListData();
        ItemsSource = data;
        VerticalOptions = LayoutOptions.FillAndExpand;
        BackgroundColor = Color.Transparent;

        // AndroidではItemTemplateで使用しているImageCellのTextが水色になってしまいます。
        // ImageCellではなくViewCellでItemTemplateを作成すると回避できるようです。
        var cell = new DataTemplate(typeof(ImageCell));
        cell.SetBinding(TextCell.TextProperty, "Title");
        cell.SetBinding(ImageCell.ImageSourceProperty, "IconSource");

        ItemTemplate = cell;
    }
}

/// <summary>
/// ListView のデータ用のクラスです。TargetTypeに遷移先ページを指定します。
/// </summary>
public class MenuItem
{
    //メニューに表示される題名をセットします。
    public string Title { get; set; }
    //アイコンファイルを指定します。
    //Androidは \アプリ名.Droid\Resources\drawableフォルダの画像ファイルを指定します。
    //iOSは \アプリ名.iOS\Resourcesフォルダの画像ファイルを指定します。
    public string IconSource { get; set; }
    // この Type で移動先のページクラスを指定しています。
    public Type TargetType { get; set; }
}

/// <summary>
/// ListView のデータクラスです。
/// </summary>
public class MenuListData : List<MenuItem>
{
    public MenuListData()
    {
        this.Add(new MenuItem()
        {
            Title = "TopPage",
            IconSource = "top40.png",
            TargetType = typeof(DetailPage) //Detailに設定するContentPage名を入力します。
        });
    }
}

※メニューをタップした際にどのページがタップされたかを取得するには、MenuPageクラス内にてMenu.ItemSelectedイベントを実装することにより、(MenuItem)Menu.SelectedItemで取得できます。



2.MasterDetailPageを作成する

PCLにてStartPage.xaml.cs

<? xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns = "http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:view="clr-namespace:アプリ名;assembly=アプリ名"
             x:Class="アプリ名.StartPage"
             Title="アプリ名"
             NavigationPage.TitleIcon="icon.png">
<!--以下のようにxamlでMenuPageを設定することもできます。-->
  <!--<MasterDetailPage.Master>
    <view:MenuPage />
  </MasterDetailPage.Master>-->
</MasterDetailPage>


PCLにてStartPage.cs

public partial class StartPage : MasterDetailPage
{
public NavigationPage NaviPage = null;
    public StartPage() : base()
    {
        InitializeComponent();
    //Menuページでクリックしたページに遷移できるようにイベント設定
var menuPage = new MenuPage();
menuPage.Menu.ItemSelected += (sender, e) => NavigateTo(e.SelectedItem as MenuItem);
//初回の親子関係を設定する
MasterBehavior = MasterBehavior.Popover;
        this.Master = new アプリ名.MenuPage();
this.NaviPage = new NavigationPage(new アプリ名.DetailPage());
        this.Detail = this.NaviPage;
    }
void NavigateTo(MenuItem menu)
{
//Detailページを切り替えます
Page nextPage= (Page)Activator.CreateInstance(menu.TargetType);
this.NaviPage.Navigation.PushAsync(nextPage);
this.IsPresented = false;
}
}

※アプリ名.DetailPageはContentPageを継承した普通のページです。
※ネームスペースは割愛しています。



3.起動の設定を変更します。

App.cs

public class App : Application
{
    public App()
    {
        MainPage = new アプリ名.StartPage();
    }
}


2017/07/11追記
iOSでメニューアイコンが表示されなかった不具合のあるソースを正しく修正しました。



当ブログの内容をまとめた Xamarin逆引きメニュー は以下のURLからご覧になれます。
http://itblogdsi.blog.fc2.com/blog-entry-81.html


関連記事

コメント

コメントの投稿

アルバム

広告

プロフィール

石河 純


著者名 :石河 純
自己紹介:素人上がりのIT技術者。趣味は卓球・車・ボウリング

IT関連の知識はざっくりとこんな感じです。
【OS関連】
WindowsServer: 2012/2008R2/2003/2000/NT4
Windows: 10/8/7/XP/2000/me/NT4/98
Linux: CentOS RedHatLinux9
Mac: macOS Sierra 10.12 / OSX Lion 10.7.5 / OSX Snow Leopard 10.6.8
【言語・データベース】
VB.net ASP.NET C#.net Java VBA
Xamarin.Forms
Oracle10g SQLServer2008R2 SQLAnywhere8/11/16
ActiveReport CrystalReport ReportNet(IBM)
【ネットワーク関連】
CCNP シスコ技術者認定
Cisco Catalyst シリーズ
Yamaha RTXシリーズ
FireWall関連
【WEB関連】
SEO SEM CSS IIS6/7 apache2

休みの日は卓球をやっています。
現在、卓球用品通販ショップは休業中です。