9.Prism_ボタン押下可否のバインディング

こんにちは、ゆたんぽです。

本日は、ボタン押下可否のバインディングを説明していきます。

「ここではボタン押してほしくないなー」という状況でボタンを押させなくすることができるので、アプリケーションでの間違いなどをなくすことができます。

短い内容ですが、よく利用するので是非確認していってください。

今回は、 起動直後はView4ボタンを押せない状況にして、 「システム日時の更新ボタン」を押すとView4ボタンが押せるような実装にします。


ObservesCanExecuteを使用する場合(ViewModel側)

ObservesCanExecuteを使用する場合は、ViewModel側の実装のみで終わらせることができるのがメリットです。

以下で実装方法を説明していきます。

MainWondowViewModelの実装

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs; 
using Sample.Views;
using System;

namespace Sample.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private readonly IRegionManager _regionManager;

        private readonly IDialogService _dialogService;

        private string _title = "Sample Application";

        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private string _systemData = DateTime.Now.ToString("yyyy年MM月dd日  HH時mm分ss秒");

        public string SystemData
        {
            get { return _systemData; }

            set { SetProperty(ref _systemData, value); }
        }

        private bool _canView4 = false;//①

        public bool CanView4
        {
            get { return _canView4; }

            set { SetProperty(ref _canView4, value); }
        }

        public DelegateCommand UpdateButton { get; }

        public DelegateCommand ShowView1Button { get; }

        public DelegateCommand ShowView2Button { get; }

        public DelegateCommand ShowView3Button { get; }

        public DelegateCommand ShowView4Button { get; }

        public MainWindowViewModel(IRegionManager regionManager,IDialogService dialogService)
        {
            _regionManager = regionManager;

            _dialogService = dialogService;

            UpdateButton = new DelegateCommand(UpdateButtonExe);

            ShowView1Button = new DelegateCommand(ShowView1ButtonExe);

            ShowView2Button = new DelegateCommand(ShowView2ButtonExe);

            ShowView3Button = new DelegateCommand(ShowView3ButtonExe);

            ShowView4Button = new DelegateCommand(ShowView4ButtonExe)
                .ObservesCanExecute(()=>CanView4);//②
        }

        private void UpdateButtonExe()
        {
            SystemData = DateTime.Now.ToString("yyyy年MM月dd日  HH時mm分ss秒");
            CanView4 = true;//③
        }

        private void ShowView1ButtonExe()
        {
            _regionManager.RequestNavigate("ContentRegion",nameof(View1));
        }

        private void ShowView2ButtonExe()
        {
            var p = new NavigationParameters();

            p.Add(nameof(View2ViewModel.View2Label),SystemData);

            _regionManager.RequestNavigate("ContentRegion", nameof(View2),p);
        }

        private void ShowView3ButtonExe()
        {
            var p = new DialogParameters();
            p.Add(nameof(View3ViewModel.View3TextBox),SystemData);
            _dialogService.ShowDialog(nameof(View3),p,View3Close);
        }

        private void View3Close(IDialogResult dialogResult)
        {
            if(dialogResult.Result == ButtonResult.OK)
            {
                SystemData = dialogResult.Parameters.GetValue<string>(nameof(View3ViewModel.View3TextBox));
            }
        }

        private void ShowView4ButtonExe()
        {
            _regionManager.RequestNavigate("ContentRegion", nameof(View4));
        }

    }
}

上記に実装したプログラムの内容を説明していきます。

①まず、ボタンを押せるか押せないかの状態をbool型で表します。今までのデータバインド同様に実装していきます。

② 以前作成していた、View4の表示ボタンである「ShowView4Button」に、ObservesCanExecuteを追加で実装します。これが、今回のボタン押下可否のプロパティになっており、指定したbool型の変数がtrueならば、「ボタンを押せる」、falseなら「ボタンを押せない」状況を作り出すことができます。

③システム日時の更新タイミングで”CanView4”をtrueにして、ボタンを押せる状況にするようにします。

上記の3つの実装を行うだけで設定できました。

実際に起動してみましょう。

起動時は、上記のようにView4のボタンが押せない状況になっています。
これは、CanView4が初期値でfalseに設定されているからです。
次に「時間更新」ボタンを押すと、View4が押せる状況になっています。
これは、押した時にCanView4がtrueになっているからです。

このようにボタンの押下可否が確認できれば成功です。


IsEnabledを使用する場合(xaml側)

IsEnabledはxaml側のボタンに直接データバインディングするやり方です。

こちらは、xaml側とViewModel側の実装が必要になります。

以下で説明していきます。

View4の実装

<Window x:Class="Sample.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="500" Width="525"
        WindowStartupLocation="CenterScreen">
    <Grid>
        <StackPanel>
            <Label Content="システム日時"/>
            <Label Content="{Binding SystemData}"/>
            <Button Content="時間更新"
                    Command="{Binding UpdateButton}"/>
            <Button Content="View1"
                    Command="{Binding ShowView1Button}"/>
            <Button Content="View2"
                    Command="{Binding ShowView2Button}"/>
            <Button Content="View3"
                    Command="{Binding ShowView3Button}"/>
            <Button Content="View4"
                    Command="{Binding ShowView4Button}"
                    IsEnabled="{Binding CanView4}"/>
            <ContentControl prism:RegionManager.RegionName="ContentRegion" />
        </StackPanel>
    </Grid>
</Window>

上記のようにIsEnabledを”CanView4”でデータバインドします。

IsEnabledをbool型の変数でデータバインドすることでボタン押下可否を設定できるようになります。

MainWindowViewModelの実装

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs; 
using Sample.Views;
using System;

namespace Sample.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private readonly IRegionManager _regionManager;

        private readonly IDialogService _dialogService;

        private string _title = "Sample Application";

        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private string _systemData = DateTime.Now.ToString("yyyy年MM月dd日  HH時mm分ss秒");

        public string SystemData
        {
            get { return _systemData; }

            set { SetProperty(ref _systemData, value); }
        }

        private bool _canView4 = false;

        public bool CanView4
        {
            get { return _canView4; }

            set { SetProperty(ref _canView4, value); }
        }

        public DelegateCommand UpdateButton { get; }

        public DelegateCommand ShowView1Button { get; }

        public DelegateCommand ShowView2Button { get; }

        public DelegateCommand ShowView3Button { get; }

        public DelegateCommand ShowView4Button { get; }

        public MainWindowViewModel(IRegionManager regionManager,IDialogService dialogService)
        {
            _regionManager = regionManager;

            _dialogService = dialogService;

            UpdateButton = new DelegateCommand(UpdateButtonExe);

            ShowView1Button = new DelegateCommand(ShowView1ButtonExe);

            ShowView2Button = new DelegateCommand(ShowView2ButtonExe);

            ShowView3Button = new DelegateCommand(ShowView3ButtonExe);

            ShowView4Button = new DelegateCommand(ShowView4ButtonExe);
        }

        private void UpdateButtonExe()
        {
            SystemData = DateTime.Now.ToString("yyyy年MM月dd日  HH時mm分ss秒");
            CanView4 = true;
        }

        private void ShowView1ButtonExe()
        {
            _regionManager.RequestNavigate("ContentRegion",nameof(View1));
        }

        private void ShowView2ButtonExe()
        {
            var p = new NavigationParameters();

            p.Add(nameof(View2ViewModel.View2Label),SystemData);

            _regionManager.RequestNavigate("ContentRegion", nameof(View2),p);
        }

        private void ShowView3ButtonExe()
        {
            var p = new DialogParameters();
            p.Add(nameof(View3ViewModel.View3TextBox),SystemData);
            _dialogService.ShowDialog(nameof(View3),p,View3Close);
        }

        private void View3Close(IDialogResult dialogResult)
        {
            if(dialogResult.Result == ButtonResult.OK)
            {
                SystemData = dialogResult.Parameters.GetValue<string>(nameof(View3ViewModel.View3TextBox));
            }
        }

        private void ShowView4ButtonExe()
        {
            _regionManager.RequestNavigate("ContentRegion", nameof(View4));
        }

    }
}

こちらは、 ObservesCanExecuteの場合で説明した内容と同じですので割愛させていただきます。

ObservesCanExecute の場合で作成した、②のObservesCanExecute実装はxaml側で行っているので実装していません。ここまでで実装が終了になります。

ここで起動を行って、「ObservesCanExecuteの場合」の結果と同じようになれば成功です。


まとめ&次回予告

今回は、「ボタン押下可否のバインディング」について記事にしていきました。

短い実装で設定できるので、ぜひ利用してください。

2通りの方法を説明しましたが、わかりやすく、実装しやすい方を選択してもらってOKです。

次回は、ReactivePropertyの実装方法を1から説明していこうと思いますのでよろしくお願いします。

また、xaml側で設定することもできるので是非

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です