WPF_Prism_DelegateCommand

DelegateCommandについて

DelegateCommandとは

DelegateCommandは、ViewModelのメソッドを呼び出すためのICommand実装クラスです。

DelegateCommandを利用することで、メソッドごとにICommandインターフェースを持ったクラスを用意する手間を省くことができます。


public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod);

DelegateCommand実装例

ViewModel

コンストラクタでDelegateCommandインスタンスを生成します。


using Prism.Commands;
using Prism.Mvvm;

namespace WpfPrismMvvm
{
    public class MainWindowViewModel : BindableBase
    {
        private string _bindtext;
        public string BindText
        {
            get { return _bindtext; }
            set { SetProperty(ref _bindtext, value); }
        }

        public DelegateCommand ButtonClickedCommand { get; private set; }

        public MainWindowViewModel()
        {
            ButtonClickedCommand = new DelegateCommand(
                () => { BindText += "The button is Clicked!\r\n"; }, // 実行処理
                () => true); // 実行可否:trueなので実行可能
        }
    }
}

xaml

ボタンにコマンドを割り当てます。


<Window x:Class="WpfPrismMvvm.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="320" Width="480">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>

        <TextBox Text="{Binding BindText, UpdateSourceTrigger=PropertyChanged}"
                 x:Name="EditBox" Margin="10" TextWrapping="Wrap" IsReadOnly="True" Grid.Row="0"/>
        <Button Command="{Binding ButtonClickedCommand}" Content="Execute DelegateCommand"  Grid.Row="1" />
    </Grid>
</Window>

xaml.cs

DelegateCommandを利用することで、以降UI変更(コマンドが追加されること)があっても、コードビハインドは変更する必要がありません。


using System.Windows;

namespace WpfPrismMvvm
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            MainWindowViewModel vm = new MainWindowViewModel();
            this.DataContext = vm;
        }
    }
}

DelegateCommand実行可否の切り替え

canExecuteMethodの設定

canExecuteMethodのbool値により、コンポーネントがDisableになります。


ButtonClickedCommand = new DelegateCommand(
    () => { BindText += "The button is Clicked!\r\n"; },
    () => false);

ObservesProperty

アプリケーション実行中はボタンDisable化するようなcanExecuteMethodの動的切り替えを行う場合はObservesPropertyを利用します。


using Prism.Commands;
using Prism.Mvvm;
using System.Threading.Tasks;

namespace WpfPrismMvvm
{
    public class MainWindowViewModel : BindableBase
    {
        private string _readtext;
        public string ReadText
        {
            get { return _readtext; }
            set { SetProperty(ref _readtext, value); }
        }

        private string _inputText;
        public string InputText
        {
            get { return _inputText; }
            set { SetProperty(ref _inputText, value); }
        } 

        public DelegateCommand ButtonClickedCommand { get; private set; }

        public MainWindowViewModel()
        {
            ButtonClickedCommand = new DelegateCommand(
                ButtonClickedProcess,
                CanExecuteButtonClickedCommand).ObservesProperty(() => InputText);
        }

        /// <summary>
        /// ボタンを実行できるか判定する処理。
        /// </summary>
        /// <returns></returns>
        private bool CanExecuteButtonClickedCommand()
        {
            return !string.IsNullOrWhiteSpace(InputText);
        }

        /// <summary>
        /// ボタン押下時の処理
        /// </summary>
        private void ButtonClickedProcess()
        {
            ReadText += InputText;
            InputText = string.Empty;
        }
    }
}

(備考)xaml


<Window x:Class="WpfPrismMvvm.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="320" Width="480">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>

        <TextBox Text="{Binding ReadText, UpdateSourceTrigger=PropertyChanged}"
                 x:Name="EditBox" Margin="10" TextWrapping="Wrap" IsReadOnly="True" Grid.Row="0"/>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <TextBox Text="{Binding InputText, UpdateSourceTrigger=PropertyChanged}" Margin="10" MinWidth="260"/>
            <Button Command="{Binding ButtonClickedCommand}" Content="Execute DelegateCommand" Margin="10" MinWidth="150" />
        </StackPanel>
    </Grid>
</Window>

関連ページ