びおりんのブログ

きままにアプリのできるまでを公開していきます

WPFのMVVMで電卓づくり(8)

計算エラーが発生したらボタンを無効化する仕組みを実装します

構想

MainModelにて計算エラーが発生した時点で表示用のErrorTextを更新し
MainViewModelにてボタンの有効無効を判定するIsEnabledをfalseに更新した後
MainViewModelでPropertyChangedイベントを発生させて
MainViewにおけるボタンを無効化します

実装

構想に沿って各MVVMクラスに追記していきます

MainModel

MainModelにて、エラー表示用のプロパティErrorTextを用意します

       // エラー表示テキスト
        public string ErrorText { get; private set; } = string.Empty;

MainModelにて、0除算時にErrorTextに「E」を代入するよう変更します

       public void Calculate(OperationKind ope)
        {
            if (!double.TryParse(this.DisplayText, out double displayValue)
             || this.AffectlValue != displayValue)
            {
                return;
            }
            switch (ope) 
            {
                case OperationKind.Plus:
                    this.OriginalValue += this.AffectlValue;
                    this.AffectlValue = 0;
                    this.DisplayText = this.OriginalValue.ToString();
                    break;
                case OperationKind.Minus:
                    this.OriginalValue -= this.AffectlValue;
                    this.AffectlValue = 0;
                    this.DisplayText = this.OriginalValue.ToString();
                    break;
                case OperationKind.Multiply:
                    this.OriginalValue *= this.AffectlValue;
                    this.AffectlValue = 0;
                    this.DisplayText = this.OriginalValue.ToString();
                    break;
                case OperationKind.Divide:
                    if (this.AffectlValue == 0)
                    {
                        this.OriginalValue = 0;
                        this.AffectlValue = 0;
                        this.DisplayText = "0";
                        this.ErrorText = "E";
                    }
                    else 
                    {
                        this.OriginalValue /= this.AffectlValue;
                        this.AffectlValue = 0;
                        this.DisplayText = this.OriginalValue.ToString();
                    }
                    break;
                default:
                    break;
            }
        }

MainViewModel

MainViewModelにて、エラー表示用プロパティErrorTextと
ボタンの有効無効を判定するプロパティIsEnabledを用意します

       public string ErrorText { get; set; }

        public bool IsButtonEnable { get; set; }

MainViewModel.PushCommandの末尾にて
this.ErrorTextにMainModel.ErrorTextを代入かつ
this.ErrorTextを参照してthis.IsButtonEnableを更新し
RaisePropertyChanged()でMainViewを更新します

           this.PushCommand = new DelegateCommand(
                param => 
                {
                    if (param == null) { return; }
                    var str = param.ToString();
                    if (model != null)
                    {
                        if (int.TryParse(str, out int num))
                        {
                            model.SetText(str);
                        }
                        else
                        {
                            model.SetOperation(str);
                        }
                        this.DisplayText = model.DisplayText;
                        RaisePropertyChanged(nameof(this.DisplayText));
                        this.ErrorText = model.ErrorText;
                        RaisePropertyChanged(nameof(this.ErrorText));
                        this.IsButtonEnable = string.IsNullOrEmpty(this.ErrorText) ? true : false;
                        RaisePropertyChanged(nameof(this.IsButtonEnable));
                        this.OperationText = model.OperationText;
                        RaisePropertyChanged(nameof(this.OperationText));
                    }
                },

MainView

四則演算子表示用の枠の上に、エラー表示用の枠を作り、ErrorTextを紐づけします

     <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <!--エラー表示-->
            <TextBlock Text="{Binding Path=ErrorText}"/>
            <!--四則演算子表示-->
            <TextBlock Grid.Row="1" Text="{Binding Path=OperationText}"/>
        </Grid>

ButtonのStyleにてボタンの有効無効を設定するIsEnabledにIsButtonEnableを紐づけします

     <!--ボタンの様式-->
        <Style TargetType="Button">
            <Setter Property="FontSize" Value="40"/>
            <Setter Property="FontStyle" Value="Normal"/>
            <Setter Property="Background" Value="Black"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="FontFamily" Value="arial"/>
            <Setter Property="Command" Value="{Binding Path=PushCommand}"/>
            <Setter Property="IsEnabled" Value="{Binding Path=IsButtonEnable}"/>
        </Style>

動作確認

起動後「1」「÷」「0」とクリックした際の画面表示
f:id:kazoojapan1985:20200505204541p:plain