【お勉強記録】WPF コマンド
久しぶりにWPF +MVVM関係です。 データバインディングについては基本的な部分は以前やりまして、今回はコマンドについて勉強しました。
コマンド
コマンドはXamlでの操作に対応して、実行される処理を定義したもの?みたいです。 コマンドとバインディングするにはICommandインターフェースの実装したクラスが必要なようです。
そのICommandインターフェースを見てみると以下のようになっています。
// 概要: // コマンドを定義します。 public interface ICommand { // 概要: // コマンドを実行するかどうかに影響するような変更があった場合に発生します。 event EventHandler CanExecuteChanged; // 概要: // 現在の状態でこのコマンドを実行できるかどうかを判断するメソッドを定義します。 // // パラメーター: // parameter: // コマンドで使用されたデータ。 コマンドにデータを渡す必要がない場合は、このオブジェクトを null に設定できます。 // // 戻り値: // このコマンドを実行できる場合は true。それ以外の場合は false。 bool CanExecute(object parameter); // // 概要: // コマンドの起動時に呼び出されるメソッドを定義します。 // // パラメーター: // parameter: // コマンドで使用されたデータ。 コマンドにデータを渡す必要がない場合は、このオブジェクトを null に設定できます。 void Execute(object parameter); }
コマンドで実行される実処理を担当する部分としてExecuteとコマンドが実行可能かを判断する他の部分に分かれています。
サンプル
理解のために実際に書いてみました。 「テキストボックスに何かしらの値が入っていれば、実行ボタンが押せる。(=何か入れないと実行できない。)」
ますはcs側から…。
ExecuteCommandクラスでICommandを実装しています。 CanExecuteでは、実行可能になる条件を、Executeでは実行処理をそれぞれ実装しています。 実装したExexuteCommandクラスを、実際にXamlと結ばれるCommandViewModelでプロパティとして使用しています。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Input; namespace Command { public class CommandViewModel : INotifyPropertyChanged { public string Text { get { return text; } set { text = value; NotifyPropertyChange("Text"); } } private string text; public ICommand Command { get { return command ?? (command = new ExecuteCommand(this)); } } private ICommand command; public event PropertyChangedEventHandler PropertyChanged; protected void NotifyPropertyChange([CallerMemberName]string propertyName = null) { if (this.PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } private class ExecuteCommand: ICommand { private CommandViewModel commandViewModel; //コンストラクタ public ExecuteCommand(CommandViewModel viewModel) { commandViewModel = viewModel; commandViewModel.PropertyChanged += (sender, e) => { if (CanExecuteChanged != null) { CanExecuteChanged(sender, e); } }; } public bool CanExecute(object parameter) { return !String.IsNullOrEmpty(commandViewModel.Text); } public event EventHandler CanExecuteChanged; public void Execute(object param) { MessageBox.Show("実行"); } } } }
Xaml側では、DataContextプロパティで先ほどのCommandViewModelをセットして、 ButtonのCommandプロパティにバインドしています。
<Window x:Class="Command.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Command" Title="MainWindow" Height="350" Width="525"> <Window.DataContext> <local:CommandViewModel x:Name="viewModel"/> </Window.DataContext> <StackPanel> <TextBox Text="{Binding Text}"></TextBox> <Button Content="Focus用"></Button> <Button Content="実行" Command="{Binding Command}"></Button> </StackPanel> </Window>
以下実行結果です。
実行と書いてあるボタンが押下不可状態になっています。
テキストボックスに何らか入力すると実行可能に!(今回はサンプルだしフォーカスが移動必要なままです。)
ちなみに押すと「実行」とメッセージボックスが出ます。
次回以降はMVVM
データバインディングとコマンドを一通り見られたので、いよいよ今後はMVVMについて学んでいく予定です。 まずはTodoアプリでも作ってみたいと思います。
これから学んでいきたいこと(2017/08)
自分を奮い立たせる&今後の行動指針にするために、これから学んでいきたいことを書き出しました。
Microsoft系
デスクトップアプリケーション
- WPF(MVVM)
- UWP
- Xamarin
WEB系(サーバーサイド)
- ASP.NET MVC
- ASP.NET Identity
- Azure
デスクトップアプリではWPFでうまく、XAMLとBindingとMVVMを身に着けて、それを活かしてUWPやXamarinの方にシフトしていけたらなという作戦です。 Web系はMVCの思想をしっかり習得したいです。そのうえで何かをAzureの上で動かせたら最高ですが、費用の問題があります。 他にもUnityとかも触れたいですが、しばらくは優先順位は低めに置いておきます。
クライアントサイド
altJs
- TypeScript
ライブラリ
- jQuery
- React
フレームワーク
- Backbone.js
- Vue.js
- Angular
- Flux(Redux)
JavaScript界隈について全くわからない状態です。そもそもこの分け方でよろしいのかすら怪しい。 色々な思想で作られたライブラリやアーキテクチャがあるので、まずはそれぞれを軽く見ていって、自分に合ったものを深堀できたら最高です。
データベース(SQL)
- オプティマイザや実行プランを意識したSQLを書けるように…
- MySQL
- PostgreSQL
とにかくパフォーマンスの良いクエリが書けるようになりたいです。 一番業務に活きる分野かもしれません。
ソース管理
- Git(GitHub)
実はGitよくわからないのです。 これはやばい… 早急にどうにか
その他
きれいなコードが書けるのはこの先、流行のライブラリやアーキテクチャが移り変わっていっても変わらず大切にされる能力だと思うので、ここは継続して学習していかなくてはなりませんね。 テストに関しても、保守を考えるようになってくると絶対外せない部分だと思うので、はじめから意識していきたいです。
感想
書き出してみてめちゃくちゃやりたい(やらなければいけない)ことがあるなぁと実感。時間を無駄にできませんな。 本当は期限とか設けて効率よくやっていくのが重要なのでしょうが、まぁそこまで自分を追い込むとできない時に楽しさが辛さに変わるので、とりあえずは保留。 サーバサイドをC#にすると、使えるサーバ系のサービスがぐっと減るのと、今後の展開も考えてRuby(Rails)もやっておきたいなぁ~