質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.80%

C# WPFでボタンのenableが変化させられない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,465

score 19

C#   WPF   .NETCore3.0   で
テキストボックスから入力されるcodeの内容が正しければ
ボタンが押せる様になり、ボタンを押すとDataGridの内容を変更させる
プログラムを作っています


  
  
ボタンは下記の様に配置しています

MainWindow.xaml

<Button
            x:Name="btn_refresh_info"
            Grid.Row="3"
            Grid.Column="4"
            Command="{Binding RefreshDataGrid}"
            Content="{StaticResource string_refresh_info}" />


  
  
ボタン押下時のコマンドはViewModelに記述しています

Project.cs

public class Project : INotifyPropertyChanged
    {
        public ICommand RefreshDataGrid { get; set; } **←これをボタンのコマンドにバインドしています**

        public Project()
        {
            refreshInfoCommand = new RefreshInfoCommand(this, new DataOperator());
            RefreshDataGrid = refreshInfoCommand; 
        }

        private string code;
        public string Code
        {
            get
            { return code; }

            set
            {
             **※このcodeが書き換えられたら、RefreshDataGridクラスの"CanExecute"が実行され
              codeの内容によってボタンのenableを変更される様にしたい**
              
                code = value;
                NotifyPropertyChanged("Code");
                NotifyPropertyChanged("CodeAndName");

            }
        }
    }


  
  
ボタンに紐づけているコマンドの中身は下記の通りです
RefreshInfoCommand.cs

 internal class RefreshInfoCommand : ICommand
    {

        private readonly Project vm;
        private readonly DataOperator dataOperator;

        public RefreshInfoCommand(Project viewmodel, DataOperator dataOperator)
        {
            this.vm = viewmodel;
            this.dataOperator = dataOperator;

        }


        public bool CanExecute(object parameter)
        {
            if ((vm.Code != "") && (int.TryParse(vm.Code, out int _)))
            {
                return true;
            }
            return false;

        }

        public void Execute(object parameter)
        {

            GetDataGridData();
            OutputDataGridData();

        }

        private void GetDataGridData()
        {
                *** 省略 ***
        }

        private void OutputDataGridData()
        {
                *** 省略 ***
        }

   }

  

上記の様にコードを記述しましたが
起動時にcodeが""で立ち上がり、ボタンが押せない状態で起動し(これは想定通りの動作)
textboxからcodeを入力しますが、ボタンの使用可否が変化しませんでした

仕方がないのでRefreshInfoCommand.cs

 public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged?.Invoke(this, new EventArgs());
        }


を追加し、(Project.cs内からCanExecuteChangedを叩こうとするとエラーになり、叩けませんでした)

Project.cs
public string Codeのset内に

refreshInfoCommand.RaiseCanExecuteChanged();


として、自力で CanExecuteChangedを叩きに行く事にしました。

  

上記の変更でとりあえず望み通りに動いているのですが、
・変化のきっかけが多数ある時に、いちいち叩きに行かないとならないのか?
・バインドの機能があるのだから、もっとスマートなやり方がありそう・・・と
邪道感が否めません

  
・このやり方が一般的に許容されるやり方なのか?
・王道のやり方はこうです

など、をご指導頂ければと思い投稿しました
ご教授をお願いします

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

・変化のきっかけが多数ある時に、いちいち叩きに行かないとならないのか?

はい

・バインドの機能があるのだから、もっとスマートなやり方がありそう

MVVMインフラを使えば多少は負荷が軽減されると思います。
「書かないコードにバグは無い」ので、私はICommand, INotifyPropertyChangedの実装など自分では行いません。
何より自分で実装すると書かねばならない多くのドキュメントが[Prismを使ってます]などの一言で済みます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/22 09:00

    ご回答ありがとうございます。
    とりあえず、方向として邪道側では無さそうで安心しました。

    ずっとWindowsForms で自作ソフトを作っていたのですが
    それが時代遅れになっている事を最近知り
    WPF + C# + .NET Core の環境を現在勉強中です
    最初なので、フレームワークなどのツールは使用しない方向で組んで
    基本的な組み方を勉強し、その後それをツールに置き換える様にして
    動きを理解したいと思っていました
    (正直、どれがWPFの純粋な機能で、どれがフレームワークの機能なのかも
     理解できていない状態です。 ^^; )

    Prismと言う存在は見かけた事がありますが、何に役立つのか知りませんでしたが
    「[Prismを使ってます]などの一言で済む」 様な
    便利かつ当たり前に使用される機能である事が分かりましたので
    今後、それについても勉強し、使用して行きたいと思います

    キャンセル

  • 2020/01/23 17:14

    既にWPFも時代遅れですから、せっかく新しく学ぶならもっと新しいものをお勧めします。
    WPF と同じようにXAMLを使う Xamarin とか如何でしょう?

    キャンセル

  • 2020/02/03 16:29

    ご返信をありがとうございます
    Xamarin ←聞いた事はあります。
    調べてみましたがandroidアプリも出来る様ですし
    C# + XAML の構成も少し分かって来て、それが応用出来る感じなので
    今、移植している物がとりあえず形になったら、次の移植はXamarinでTryしてみたいと思います
    (もたもたしてると直ぐに時代遅れの技術になるので、早めにやらないといけませんね ^^;)

    度々のアドバイスをありがとうございました

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る