XAMLを使わないWPF入門29「ICommand.CanExecuteでボタンを実行不可にする。」

コンピュータ

タイマーを使って起動後5秒にボタンを無効化します。

・起動直後はボタンが有効
image

・5秒経過すると無効化
image

ファイル名:NoXAML29.csproj


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

</Project>

ファイル名:App.cs


using System;
using System.Windows;

namespace NoXAML29;

public class App : Application
{
    [STAThread]
    public static void Main(string[] args)
    {
        var app = new App();
        app.Run();
    }

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        var win = new MainWindow();
        win.Show();
    }
}

ファイル名:AssemblyInfo.cs


using System.Windows;

[assembly:ThemeInfo(
    ResourceDictionaryLocation.None,            //where theme specific resource dictionaries are located
                                                //(used if a resource is not found in the page,
                                                // or application resource dictionaries)
    ResourceDictionaryLocation.SourceAssembly   //where the generic resource dictionary is located
                                                //(used if a resource is not found in the page,
                                                // app, or any theme specific resource dictionaries)
)]

ファイル名:Helpter\RelayCommand.cs


using System.Windows.Input;

public class RelayCommand : ICommand
{
    private readonly Action _execute;
    private readonly Func<bool> _canExecute;
    public event EventHandler? CanExecuteChanged;

    public RelayCommand(Action execute, Func<bool>? canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute ?? (() => true);
    }

    public bool CanExecute(object? parameter) => _canExecute();

    public void Execute(object? parameter) => _execute();

    public void RaiseCanExecuteChanged()
        => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}

ファイル名:View\MainWindow.cs


using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;

namespace NoXAML29;

public class MainWindow : Window
{
    private RelayCommand _myCommand;
    private bool _canExecuteFlag = true;

    public MainWindow()
    {
        Title = "ICommand.CanExecute サンプル";
        Width = 300;
        Height = 150;

        // コマンド作成
        _myCommand = new RelayCommand(
            () => MessageBox.Show("ボタン実行!"),
            () => _canExecuteFlag
        );

        // ボタン生成
        var button = new Button
        {
            Content = "実行ボタン",
            Command = _myCommand,
            Width = 100,
            Height = 40,
            Margin = new Thickness(20)
        };

        Content = new StackPanel
        {
            VerticalAlignment = VerticalAlignment.Center,
            HorizontalAlignment = HorizontalAlignment.Center,
            Children = { button }
        };

        // タイマー設定(5秒後に無効化)
        var timer = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(5)
        };
        timer.Tick += (s, e) =>
        {
            timer.Stop();
            _canExecuteFlag = false;
            _myCommand.RaiseCanExecuteChanged();
        };
        timer.Start();
    }
}

コメント