LoginSignup
0
0

More than 5 years have passed since last update.

Xamarin.FormsプロジェクトにMVVM Lightを導入する(必要クラスを自動生成してくれないため)

Last updated at Posted at 2018-12-04

MVVM LightにはXamarin.Androidのテンプレートはあるけど、データバインディングが手書きの上コードビハインドだらけなので、Formsを利用したい。でも公式ページ通りに導入しても必要なLocatorクラスなどを自動生成してくれない。よって今回は手動で導入する手順をまとめました。

1. NuGetからMVVM Lightをインストールする

まずはソリューションを右クリック、「ソリューションのNuGetパッケージを管理」を選択します。
xamarinmvvmlight1.png

mvvmlight」で検索、全プロジェクトにチェックを入れてインストールします。
ここではAndroidしかないがiOS, UWP等ある場合も同様です。
xamarinmvvmlight2.png

規約承認などをして出力ウィンドウに===Finished===と出たら完了です。

必要なファイルの作成

まずはMainViewModelから。ここではMVVM関係のファイルはMvvm名前空間に入れてあります。

時刻を表示するためのサンプルです。

MainViewModel.cs
using System;
using System.Threading.Tasks;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Threading;

namespace FormsMvvm.Mvvm
{
    public class MainViewModel : ViewModelBase
    {
        private bool _runClock;

        private string _clock;
        public string Clock
        {
            get
            {
                return _clock;
            }
            set
            {
                Set(ref _clock, value);
            }
        }


        public MainViewModel()
        {
            StartClock();
        }

        public void StartClock()
        {
            _runClock = true;

            Task.Run(
                async () =>
                {
                    while (_runClock)
                    {
                        DispatcherHelper.CheckBeginInvokeOnUI(
                            () =>
                            {
                                Clock = DateTime.Now.ToString("HH:mm:ss");
                            });

                        await Task.Delay(1000);
                    }
                });
        }

        public void StopClock()
        {
            _runClock = false;
        }
    }
}

次にViewModelLocator。通常はコンストラクターでModelのなにやらを記述しますが、今回は省略。(今度書き足します)

ViewModelLocator.cs
using System.Diagnostics.CodeAnalysis;
using GalaSoft.MvvmLight.Ioc;
using CommonServiceLocator;

namespace FormsMvvm.Mvvm
{
    public class ViewModelLocator
    {
        [SuppressMessage("Microsoft.Performance",
            "CA1822:MarkMembersAsStatic",
            Justification = "This non-static member is needed for data binding purposes.")]
        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }

        public static bool UseDesignTimeData
        {
            get
            {
                return false;
            }
        }

        static ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            SimpleIoc.Default.Register<MainViewModel>();
        }

        public static void Cleanup()
        {
        }
    }
}

xaml上でViewModelLocatorを参照できるようにするために、App.xamlにViewModelLocatorを配置します。

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="FormsMvvm.App"
             xmlns:vm="clr-namespace:FormsMvvm.Mvvm"> <!--ここと-->
    <Application.Resources>
        <vm:ViewModelLocator x:Key="Locator" /> <!--ここ-->
    </Application.Resources>
</Application>

最後にDispatcherHelperの初期化をApp.xaml.csのコンストラクタで行います。

App.xaml.csのコンストラクタ内に一行追加
DispatcherHelper.Initialize();

これにて導入完了です。

データバインディングする

これでようやくxamlから簡単にデータバインディングできるようになりました。

DataContextではなくBindingContextにLocatorをバインドします。そのためWPFと違いIntelliSenseでプロパティ名などを補完してくれません...

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:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:Exp_XamarinMvvmForms"
             xmlns:fab="clr-namespace:FuryTechs.FloatingActionButton;assembly=FuryTechs.FloatingActionButton"
             xmlns:androidWidget="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
             x:Class="Exp_XamarinMvvmForms.MainPage"

             BindingContext="{Binding Main, Source={StaticResource Locator}}"> <!--これを忘れずに-->
    <StackLayout>
        <Label Text="{Binding Clock}"
               FontSize="70" />
    </StackLayout>
</ContentPage>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0