2016年

5月

21日

Xamarin.Froms  MasterDetailPage  Menu image icon

画面左からスワイプまたは左上の文字/画像をタップするとスライドして出て来るページです。

Menuのセルにアイコンイメージをセットしています。

概要レベルで要素を一覧するマスターページと、各要素の詳細ページを管理するページです。通常、マスターページがメニュー的な役割を担うことになります。

Listview花火一覧方法もまとめています。

 

参考ページのブログサンプルを各ページごとに分割しています。

Android Windows Phone エミレーター表示


ファイル --> 新規作成  --> プロジェクト(P)...  --> Cross-Platform --> Xamarin-Forms で作成

MasterDetailPage05

Forms ContentPageを選択 RootPage.cs MenuItem.cs MenuIistData.cs MenuIistView.cs MenuPage.cs ListItem.cs ListItemCell.csの追加

RootPageの書き換え

using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection.Emit;

using System.Text;

 

using Xamarin.Forms;

 

/// <summary>

/// MasterDetailPage の定義です。Master(左側) と Detail(各子ページ) を指定します。

/// </summary>

namespace MasterDetailPage05

{

    public class RootPage : MasterDetailPage

    {

        public RootPage()

        {

            var menuPage = new MenuPage();

            // Menu ページの ListView Menu を選択した時に NavigateTo メソッドに SelectedItem を渡します。

            menuPage.Menu.ItemSelected += (sender, e) => NavigateTo(e.SelectedItem as MenuItem);

 

            Master = menuPage;

 

            // Detail は NavigationPage で呼び出した方が良いです。(左からのスワイプで Master を出せるが操作しづらい)

            // バーの色を変えています。

            var detail = new NavigationPage(new TopPage());

            detail.BarBackgroundColor = Color.FromHex("3498DB");

            detail.BarTextColor = Color.White;

            Detail = detail;

        }

 

        /// <summary>

        /// ページ遷移のメソッドです。

        /// </summary>

        /// <param name="menu">MenuItem</param>

        void NavigateTo(MenuItem menu)

        {

            // menuPage の List<MenuItem> の選択値を MenuItem で受け取っているので

            // 予め定義されたページに移動できるってことは分かるんですが、凄いですね。

            Page displayPage = (Page)Activator.CreateInstance(menu.TargetType);

 

            // 同じく各ページに移動する時にもバーの色を再設定 (このやり方では必須)

            var detail = new NavigationPage(displayPage);

            detail.BarBackgroundColor = Color.FromHex("3498DB");

            detail.BarTextColor = Color.White;

            Detail = detail;

 

            IsPresented = false;

        }

    }

}

MenuPageの書き換え

using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection.Emit;

using System.Text;

 

using Xamarin.Forms;

 

/// <summary>

/// 左側のメニューページクラスです。

/// </summary>

namespace MasterDetailPage05

{

   

    public class MenuPage : ContentPage

    {

        public ListView Menu { get; set; }

 

        public MenuPage()

        {

            Icon = "menu.png"; // Icon を設定すると左側が文字でなくアイコンで置き換わります。

            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;

        }

    }

}

MenuListViewの書き換え

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

using Xamarin.Forms;

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

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

            ItemTemplate = cell;
        }
    }
}

MenuItemの書き換え

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

using Xamarin.Forms;

namespace MasterDetailPage05
{
    public class MenuItem
    {
        public string Title { get; set; }

        public string IconSource { get; set; }
        // この Type で移動先のページクラスを指定しています。
        public Type TargetType { get; set; }
    }
}

MenuListDataの書き換え

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

using Xamarin.Forms;

namespace MasterDetailPage05
{
    public class MenuListData : List<MenuItem>
    {
        public MenuListData()
        {
            this.Add(new MenuItem()
            {
                Title = "Top",
                IconSource = "home.png",
                TargetType = typeof(TopPage)
            });

            this.Add(new MenuItem()
            {
                Title = "花火一覧",
                IconSource = "search.png",
                TargetType = typeof(SecondPage)
            });

            this.Add(new MenuItem()
            {
                Title = "花火撮影タイミング",
                IconSource = "info.png",
                TargetType = typeof(ThirdPage)
            });
        }
    }
}

TopPage.cs SecondPage.cs ThirdPage.cs NextPage1.csの追加

TopPage.cs の追加

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

using Xamarin.Forms;

 

namespace MasterDetailPage04

{

    public partial class TopPage : ContentPage

    {

        public TopPage()

        {

            InitializeComponent();

 

            Title = "Top";

 

            Content = new Image

            {

                Source = ImageSource.FromResource("MasterDetailPage04.Images.classmethod_Top.png"),

                // アスペクトを設定

                Aspect = Aspect.AspectFit

            };

        }

    }

}

ListItem.cs の書き換え

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

using Xamarin.Forms;

namespace MasterDetailPage05
{
    public class ListItem
    {
        public string Source { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public int Row { get; set; }
    }
}

SecondPage.cs の書き換え

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

using Xamarin.Forms;

namespace MasterDetailPage05
{
    public partial class SecondPage : ContentPage
    {
        public SecondPage()
        {
            Title = "花火一覧";

            var listView = new ListView();

            // Source名:Android「-」「@2x」不可
            // ListItemサブクラスを参照
            listView.ItemsSource = new ListItem[] {
                new ListItem {Source =

                         "fire1s.png", Title = "1.千輪 光跡編", Description="ISO:100 絞り:F13", Row=0},
                new ListItem {Source =

                         "fire2s.png", Title = "2.柳 光跡編", Description="ISO:400 絞り:F8", Row=1},
                new ListItem {Source =

                         "fire3s.png", Title = "3.菊先 光跡編", Description="ISO:100 絞り:F13", Row=2}
            };

            // セルの高さ
            listView.RowHeight = 84;
            listView.BackgroundColor = Color.Black;
            // ListItemCellサブクラスを参照
            listView.ItemTemplate = new DataTemplate(typeof(ListItemCell));
            Content = listView;

            // セルの選択 ナビゲーションページNextPage1に画面遷移
            listView.ItemTapped += async (sender, e) =>
            {
                ListItem item = (ListItem)e.Item;
                System.Diagnostics.Debug.WriteLine("e:" + item);
                await Navigation.PushModalAsync(new NextPage1(item.Row));
                listView.SelectedItem = null;
            };

            Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0);
        }
    }
}

ListItemCell.cs の書き換え

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

using Xamarin.Forms;

namespace MasterDetailPage05
{
    public class ListItemCell : ViewCell
    {
        public ListItemCell()
        {
            Image image = new Image
            {
                HorizontalOptions = LayoutOptions.FillAndExpand,
            };
            image.SetBinding(Image.SourceProperty, "Source");

            // セルタイトルラベル
            Label titleLabel = new Label
            {
                HorizontalOptions = LayoutOptions.FillAndExpand,
                FontSize = 20,
                FontAttributes = Xamarin.Forms.FontAttributes.Bold,
                TextColor = Color.White
            };
            titleLabel.SetBinding(Label.TextProperty, "Title");

            // セルサブタイトル
            Label descLabel = new Label
            {
                HorizontalOptions = LayoutOptions.Start,
                FontSize = 18,
                TextColor = Color.White
            };
            descLabel.SetBinding(Label.TextProperty, "Description");

            StackLayout viewLayoutImage = new StackLayout()
            {
                HorizontalOptions = LayoutOptions.Start,
                Orientation = StackOrientation.Vertical,
                Padding = 3,
                Children = { image }
            };

            StackLayout viewLayoutItem = new StackLayout()
            {
                HorizontalOptions = LayoutOptions.StartAndExpand,
                Orientation = StackOrientation.Vertical,
                Padding = 15,
                Children = { titleLabel, descLabel }
            };

            StackLayout viewLayout = new StackLayout()
            {
                HorizontalOptions = LayoutOptions.StartAndExpand,
                Orientation = StackOrientation.Horizontal,
                BackgroundColor = Color.Black,
                Children = { viewLayoutImage, viewLayoutItem }
            };

            View = viewLayout;
        }
    }
}

ThirdPage.cs の書き換え

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

using Xamarin.Forms;

 

namespace MasterDetailPage04

{

    public partial class ThirdPage : ContentPage

    {

        public ThirdPage()

        {

            Title = "花火撮影タイミング";

 

            Label homeLabel = new Label

            {

                Text = "花火撮影タイミング",

                FontSize = 40

            };

 

            var stackLayout = new StackLayout

            {

                Children = { homeLabel }

            };

 

            Content = stackLayout;

        }

    }

}

App.cs の書き換え

App.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

using Xamarin.Forms;

 

namespace MasterDetailPage05

{

    public class App : Application

    {

        public App()

        {

            // MasterDetailPageを継承したクラスを生成してMainPageとする

            MainPage = new RootPage();

        }

    }

}

まとめ

テンプレートを間違うとエラーが出ますので選択時に注意が必要です。

 

目 次