(👆 2021年11月に .NET 6 MAUI が出てくれば、WPFは廃れていくレガシー技術? 知らんけど)
「 2010年頃に流行り出した デスクトップ アプリのフレームワークね」
「 👆 2021年11月に .NET 6 の登場とともに アプリのフレームワーク MAUI が出てくれば
そっちを使う人がいるかどうかは まだ はっきりしないわね」
「 何をしたら WPF なのか コーディングだけ教えてくれだぜ」
「 👆 Visual Studio 2019 などを使って WPFアプリケーションのプロジェクトを新規作成して、 NuGetを使って LivetCask をインストールしなさい。
NuGet って何?っていう人は ここで諦めなさい」
「 👆 上に WPF アプリ(.NET Framework)
があって、下に WPF App(.NET)
があって、
どっちを使えばいいのか分からないが、試しに WPF App(.NET)
を使ってみるぜ」
「 👆 あとで GitHub に上げることを考えて 予め ローカル リポジトリを先に作っておいて、そこにプロジェクトを置こうぜ」
「 👆 こんな感じで 画面が出てくると思うが、最初にやることは……」
「 こんな画面見せられて 最初に NuGet の管理画面に行くのは 素人お断りな デザインだと思うぜ」
「 .NET Framework
と .NET
では違うのでは?」
「 👆 [Ctrl] + [C]
でコピーして [Ctrl] + [V]
連打で複製しろだぜ」
「 👆 Models
, ViewModels
, Views
の3つのフォルダーを作れだぜ。
もしかすると これは ローカルのやり方かもしれないが、各自 勝手に調べろだぜ」
「 👆 最初に飛び出るウィンドウがどれかというのは、 App.xaml の Applicationタグの StartupUri 属性にファイルパスが書いてあるから
分かれだぜ」
「 👆 Window のような 見た目をレイアウトしたいようなものは Views フォルダーの下に置けだぜ。
StartupUri 属性の値も変えろだぜ」
「 F5キーで Run してもいいが、初回は 10分ぐらいビルドにかかるから、カップ麺を食べるなら今だぜ」
「 👆 今回は 整ったレイアウトとか何もイメージできてないんで UsserControl1 という名前でいいだろ。
そこに ごちゃごちゃ 追加していこう」
「 👆 すると 左上の方を見て分かる通り UserControl1 は デザイン画面で 置けるアイテムになったぜ。
こうやって 部品を作って行けだぜ」
「 👆 例えば MainWindow の上に UserControl を配置できるわけだぜ。
この デザイナー画面、よく不調になって出てこなくなるので Visual Studio 2019 を再起動しろだぜ」
「 👆 デザイナーの使い方は 初見では無理。
グッドラック!」
「 この画面、カスタマイズできるから このようにせよ、という 定跡を組めないのよ。
デフォルトの状態で 使い続けるのも それはそれで 非効率だし」
「 👆 デザイナに置いたものが 重なってしまって ウギギギギ! となったら 画面左上の ドキュメント アウトライン
を
開けだぜ。 ツリー構造になってる。 あとは分かれ」
「 👆 そんなときは [表示] - [その他のウィンドウ] - [ドキュメント アウトライン]
で出せだぜ」
「 👆 テキストボックスを 読取専用 にするにも、 GUI から操作する方法と、
テキストエディターの XML形式ファイルを編集する方法があり、どっちも同期しているから 片方を編集すれば もう片方も編集される。
しかし GUI は カテゴリのところが名前順になってて 『あれ? 無い?』 と思うことがあるから グッドラック」
「 まあ とにかく レイアウト担当は こんなもんだぜ。 データのことは とにかく 考えないこと!
座標を調整するとか、 右揃え、左揃えにするとか、 ウィンドウのサイズを広げたときに どこが伸びるとか、
見た目だけ やれだぜ」
「 👆 画面に紐づく データの部分の実装の仕方を説明する。
しかし実際問題 レイアウト:デザイナー会社、 データ:実装会社 の2つに分かれて専門的に分業してるなんてことはなくて
まず詳細設計、次にコード実装 みたいに分かれてる」
「 デザイナーが デザイン画面使うとか、 コード担当が テキストエディター使うとかじゃないんだな」
「 デザイナー屋が Visual Studio 2019 開くわけないじゃないの。 Visual Studio 2019 上に存在する作業は全部 コード屋の仕事よ」
「 👆 とりあえず 名前の後ろに ViewModel
とでも付けとけだぜ」
「 👆 で、これから先、 WPF とか MVVM とか言われる何かをするために 変わったことを 追加でやることになるぜ。
その1つが using Livet;
を冒頭に書くことと、クラス名の横に : ViewModel
を書くことだぜ」
「 👆 普通のプロパティと違うのは セッター の方だぜ。
値が変わっていなければ 変更しない、
値が変わっていれば 変更して、 RaisePropertyChanged(プロパティ名)
を呼び出すということだぜ」
「 👆 コンボボックスに入れるのは 普通の Dictionary だな。
ディクショナリーのキーが いわゆるコンボボックスの値、 ディクショナリーの値が コンボボックスの表示になるぜ。
これも セッター で Livet の書き方をしている」
「 ゲッターで Dictionaryを取得して、それでディクショナリーの内容を変更したら Livet のコード通らないけど いいの?
イミュータブルじゃないのが気になるなあ」
「 👆 クラス ビューで見てみようぜ。 [表示] - [クラスビュー]
」
「 👆 今回は プロパティ名から TextBox
だの ComboBox
だの説明くさいものを省いてみるぜ。
理由としては そんな細かくしなくても 分かる程度のアプリだからだぜ」
「 👆 クラス ビューのタイトルバーを右クリックして 自動的に隠す
を選べだぜ」
「 で、これだけだと レイアウトと データの間になんの連携も無いんで、バインド というのを行うぜ」
xmlns:ViewModels="clr-namespace:ShogiEnteringKingScoreingWpf.ViewModels"
「 👆 ユーザーコントロールの冒頭に、上行を追加してくれだぜ。
XMLのnamespaceに ViewModels を追加してると思えだぜ」
「 👆 そのあとで DataContext プロパティの [新規]
ボタンをクリックしろだぜ」
「 👆 すると さっき作った UserControl1ViewModel を認識するようになってるので、選べだぜ」
「 👆 XAML にコードが3行書き足されたし、プロパティ ウィンドウにも UserControl1ViewModel クラスのプロパティが表示されたな」
「 Unity とか触ってたら こういうの すぐ理解しそうだな」
「 👆 じゃあ デザイナーから テキストボックスをクリックして、 プロパティ ウィンドウの Text の、
小さな四角をクリック、 データバインドの作成 を選べだぜ」
「 👆 TextBox タグに Text属性が付いたな。これでバインド済みだぜ。残りも全部やれだぜ」
「 👆 コンボボックスに 正しくデータを設定するには どうやったらいいんだぜ?」
「 👆 ItemsSource に ディクショナリー型プロパティを バインドして、」
「 👆 ComboBox のタグの末尾の きわどいところに キャレット(文字を挿入するカーソル)を合わせて [Ctrl] + [Space]
キーを打てだぜ」
SelectedValuePath="Key" DisplayMemberPath="Value"
「 👆 入力候補を使ってスペルミスをしないようにしながら、上記の属性を追加しろだぜ」
「 ボタンをクリックしたり、キーボードからショートカットを打鍵したときに 何か動くやつが コマンド だな。
インターネットで調べても チンプンカンプン なので、シンプルなやつを紹介するぜ」
「 👆 ICommand インターフェースを実装しろだぜ。 コードの全文は 次に示すぜ」
using System;
using System.Windows.Input;
namespace ShogiEnteringKingScoreingWpf.ViewModels
{
/// <summary>
/// 監視を開始するコマンドです
/// </summary>
public class MonitoringStart : ICommand
{
private bool _isEnabled = true;
/// <summary>
/// 実行できますか?
/// </summary>
public bool IsEnabled
{
get
{
return this._isEnabled;
}
set
{
if (this._isEnabled == value)
{
return;
}
this._isEnabled = value;
this.RaiseCanExecuteChanged();
}
}
/// <summary>
/// コマンドが実行可能かの状態が変わった時に通知します
/// </summary>
public event EventHandler CanExecuteChanged;
/// <summary>
/// 実行できますか?
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public bool CanExecute(object parameter)
{
return this.IsEnabled;
}
/// <summary>
/// 実行
/// </summary>
/// <param name="parameter"></param>
public void Execute(object parameter)
{
if (!this.IsEnabled)
{
return;
}
// TODO ここに処理を書く
System.Windows.MessageBox.Show("実装されていません");
}
/// <summary>
/// 実行可能かどうかの状況が変わった時に呼び出してください
/// </summary>
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
}
「 👆 データ コンテキストに さっきのコマンドを プロパティで取れるようにしとけだぜ。
そして ビルド しろ」
「 👆 ビルドしていれば さっき ICommand を実装したやつが リストに居る。選べだぜ」
「 👆 おお、ボタンをクリックしたら ダイアログボックスが出たぜ」
「 👆 実行したら IsEnabled
を false にするとして、」
「 👆 わたしは もうデータ バインディングしちゃったけど もう1回見せたろ」
「 👆 IsEnabled
プロパティを選べだぜ。これで OK」
「 ボタンを グレーアウトする命令を書くのではなく、
ボタンの IsEnabledプロパティと MonitoringStartコマンドの IsEnabledプロパティを バインドさせれば
同期するという発想なのね」
「 マナーよく作らないと どこかで無限ループしたり 何かいじったりして 破綻しそうだな」
「 👆 ビヘイビア(Behavior) と アクション(Action)とコマンド(ICommand)は別記事に書いたぜ」
📖 WPFってどうやって画面遷移すんの(^~^)?(Frame, Page 編)
「 👆 画面遷移 フレーム(Frame) と ページ(Page)は別記事に書いたぜ」
「 👆 別ウィンドウ(Window)の出し方は別記事に書いたぜ」
「 👆 画面中央 上の デザイナーで フォームをいじって 画面中央 下の .xaml を書いているとき、
どの .cs
ファイルだったかなと 画面左上の ソリューション エクスプローラーを見たら、
今 どのファイルを編集してるのか 分かんね、と思うときがあるだろ」
「 べつに どのファイルかなんか 気にしなくていいのに……」
「 👆 そんなとき、ソリューション エクスプローラーのツールボックスに並んでいる [アクティブ ウィンドウとの同期]
ボタンをクリックしてみろだぜ」
「 そんなの Visual Studio Code なら オートでやってくれるわよ?
名前は似てるけど、 Visual Studio より Visual Studio Code の方が 大変 便利よ~」
「 今はまだ 要らないと思うかも知れないが、大量のファイルがあるとき、検索で飛ぶと それが ソリューション エクスプローラーのどのファイルか調べたくなるんで、そんなとき使うぜ」
「 👆 なんか .xaml と .cs ファイルが2枚ぺったり くっついてるやつを コードビハインド と呼ぶらしいぜ。
意味としては デザインと ロジックが分かれていていいでしょ、ということらしいぜ」
「 しかし コードビハインドの ロジックの方の .cs ファイル、
コードを汚すな! とか 書かれていて ここにロジック書いたら負け! みたいな雰囲気がある……」
「 👇 ViewModelCommand 知らないと 困る。記事 書かな」
📖 wpf-view-model-command-practice
「 👆 じゃあ 試しに こういう感じで 画面遷移してみようぜ?
Web系を 15年やってたら ウィンドウの開け閉めは スキル弱ってるよな」
📖 WPFで画面遷移ってどうやんの(^~^)?(コマンドを使ったWindow編)
「 👆 リソース ディクショナリーの使い方を覚えてから 画面を作った方が効率的と思うぜ」
📖 WPFのGridとかStackPanelとかWrapPanelって何なんだぜ(^~^)?
📖 WPFでUserControlの練習をしようぜ(^~^)?
「 👆 Windowsのルックスを止める要望 まず最初に出てくるんで」
「 全然 機能の使い方の説明が終わらん。 これでは アプリケーション開発の全体図がなかなか見えないぜ。
別のやり方も やろうぜ?」
「 Microsoft が用意して欲しいよな、チュートリアル」
「 WPFの範囲なのか、 C#の範囲なのかは 切り分けた方がいいんじゃない?」
Crieitは個人で開発中です。
興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!