前回はXAMLの重複スタイルを別ファイルに定義することでコードをスッキリさせるところまで実装しました。

今回は『動き』を付けていきたいと思います。

以下の動作環境にて確認済み
  • Visual Studio 2019 Community
  • Android 9.0.99
  • .NETStandard.Library 2.0.3
  • Prism.Unity.Forms 7.1.0.431

今回実装する『動き』

今回ご紹介するコードで実現される動作は下記のとおりです。

実装内容
  • ユーザIDとパスワードの両方が入力されていた場合に、次の処理へ進む。
  • それ以外の場合、エラーメッセージをダイアログで通知する。

(余談)IsEnabledをバインドできない

コードに入る前に、「多分これで動くよな~」と思ってた箇所のご紹介。

どうやらコントロールのIsEnabledプロパティへのバインドは効かないようです。

ユーザIDとパスワードの両方が入力されている場合にログインボタンを活性化したかったのですが、別な方法を検討する必要がありました。

View

<?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:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="Sample.Views.LoginPage"
             Title="{Binding Title}">

    <StackLayout Orientation="Vertical"
                 VerticalOptions="Center"
                 HorizontalOptions="Center">

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Label Grid.Row="0"
                   Grid.Column="0"
                   Style="{StaticResource LoginPageLabel}"
                   Text="{Binding UserIdLabel}"/>

            <Entry Grid.Row="0"
                   Grid.Column="1"
                   Style="{StaticResource LoginPageEntry}"
                   Placeholder="{Binding UserIdLabel}"
                   Text="{Binding UserId}"/>

            <Label Grid.Row="1"
                   Grid.Column="0"
                   Style="{StaticResource LoginPageLabel}"
                   Text="{Binding PasswordLabel}"/>

            <Entry Grid.Row="1"
                   Grid.Column="1"
                   Style="{StaticResource LoginPageEntry}"
                   IsPassword="True"
                   Placeholder="{Binding PasswordLabel}"
                   Text="{Binding Password}"/>
        </Grid>

        <StackLayout Orientation="Horizontal"
                     HorizontalOptions="Center"
                     VerticalOptions="Center">

            <Button Text="新規登録"
                    Command="{Binding RegisterButtonClicked}"/>

            <Button Text="ログイン"
                    Command="{Binding LoginButtonClicked}"/>

        </StackLayout>

    </StackLayout>
  
</ContentPage>
前回からの変更点
  • コントロールのラベルで共通するものはバインドしてViewModelのコンストラクタで詰めるように変更。
  • ユーザ入力可能なコントロールの入力値をViewModelで取得できるようにバインド。

ViewModel

using Prism.Commands;
using Prism.Navigation;
using Prism.Services;
using System;
using System.Threading.Tasks;

namespace Sample.ViewModels
{
    public class LoginPageViewModel : ViewModelBase
    {

        #region 定数・変数

        private static string TITLE = "ログインページ";
        private static string USER_ID_LABEL = "ユーザID";
        private static string PASSWORD_LABEL = "パスワード";

        private IPageDialogService _pageDialogService;

        #endregion

        #region プロパティ

        /// <summary> ユーザID </summary>
        public string UserId { get; set; }

        /// <summary> ユーザIDラベル </summary>
        public string UserIdLabel { get; set; }

        /// <summary> パスワード </summary>
        public string Password { get; set; }

        /// <summary> パスワードラベル </summary>
        public string PasswordLabel { get; set; }

        #endregion

        #region コマンド

        public DelegateCommand RegisterButtonClicked { get; set; }
        public DelegateCommand LoginButtonClicked { get; set; }

        #endregion

        public LoginPageViewModel(INavigationService navigationService, IPageDialogService pageDialogService) : base(navigationService)
        {
            Title = TITLE;
            UserIdLabel = USER_ID_LABEL;
            PasswordLabel = PASSWORD_LABEL;

            _pageDialogService = pageDialogService;

            RegisterButtonClicked = new DelegateCommand(() => Register());
            LoginButtonClicked = new DelegateCommand(async () => await Login());
        }

        private void Register()
        {
            // 新規登録処理へ進む
        }

        private async Task Login()
        {
            if (!string.IsNullOrEmpty(UserId) && !string.IsNullOrEmpty(Password))
            {
                // ユーザIDとパスワードが入力されている場合はログイン処理へ進む
            }
            else
            {
                // 両方未入力、またはどちらかが未入力の場合はダイアログで通知する
                await _pageDialogService.DisplayAlertAsync("警告", "未入力の項目があります。", "OK");
            }
        }
    }
}
前回からの変更点
  • ログインボタン押下時に入力されたユーザIDとパスワードの入力値チェックを追加。
  • 両方入力されている場合は次の処理(未実装)へ、それ以外の場合はエラーメッセージをダイアログで通知するように変更。

特筆すべき点としては、MVVMでダイアログを表示するには『IPageDialogService』を利用します。

見え方

まとめ

まとめ
  • 『IsEnabled』プロパティはバインドできない。
  • ダイアログを表示するには『IPageDialogService』を利用する。

次回からはWebAPIとの連携部分を実装していこうと思います。

以上です。

スポンサーリンク