C#でWPF学習中「ReactiveCommandを使った条件が成立した場合のみ押せるボタン」

C# コンピュータ
C#
ReactiveCommandで実行条件を設定する方法があるようなので試してみました。

実行環境

Windows10 2004
dotnet –version 5.0.104
Visual Studio Code
PowerShell 5.1

プロジェクトの作成

mkdir プロジェクト名
cd プロジェクト名
dotnet new wpf
dotnet add package Microsoft.Xaml.Behaviors.Wpf
dotnet add package ReactiveProperty.WPF
code .

ソースコード

ファイル名:MainWindow.xaml

<Window x:Class="WpfSample25CanExec.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"
        xmlns:local="clr-namespace:WpfSample25CanExec"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <StackPanel>
            <TextBox Text="{Binding Times.Value}" />
            <Slider
                Minimum="0"
                Maximum="10"
                Value="{Binding Times.Value}"
                TickPlacement="Both" />
            <Button
                Content="実行"
                Command="{Binding ExecCommand}" />
        </StackPanel>
    </Grid>
</Window>

ファイル名:MainWindowViewModel.cs

using System.Diagnostics;
using System;
using System.Windows;
using Reactive.Bindings;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Linq;

namespace WpfSample25CanExec
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public ReactiveProperty<int> Times { get; private set; } = new ReactiveProperty<int>(1);
        public ReactiveCommand ExecCommand { get; }

        public ReactiveProperty<bool> ExecCommandFlag { get; private set; }

        public MainWindowViewModel()
        {
            ExecCommandFlag = Times
                .Select( x => (x % 2 == 1) )
                .ToReactiveProperty<bool>();

            ExecCommand = ExecCommandFlag
                .ToReactiveCommand()
                .WithSubscribe(()=>{
                    MessageBox.Show(string.Format("Times:{0}", Times.Value));
                });
        }
    }
}

使い方

スライダーの値が奇数の場合ボタンが有効化

スライダーの値が偶数の場合ボタンが有効化
ViewModelのReactiveCommandをいじってView側のBottonの有効無効が切り替わるのは不思議な感じがしますが、GUIを作っているとよく遭遇する状況ですので、便利に使わせていただこうと思います。

コメント