読者です 読者をやめる 読者になる 読者になる

Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

WPF DataGrid VS Windows Form DataGridView

おおまかなアーキテクチャ設計は出来てきて、MVVMに乗っ取った仕組みでうまいことやろうとしています。で、業務系アプリはグリッド入力がUIの8割を占めるんですけど、組み方がWPFWindows Formでは結構違うみたい。

セル内イベント捕捉

Windows Formの場合はグリッド全体に対するコードビハインドでKeyDownなどのイベントを拾える。ただ、編集可能なテキストボックスのカラムのKeyDownイベントはそこでは拾えないので
DataGridViewでセルが編集中の時にキーイベントを捕捉する: .NET Tips: C#, VB.NETにあるような方法で捕まえる。

実際に実装したシステムではたいだいこれぐらいのフックが必要だった。

カラム名 イベント 処理概要
品番 KeyDownでEnter 商品データ取得
品番 KeyDownで+key 商品一覧子画面起動
数量 KeyDown 数値チェック→合計数量変動
数量 KeyPress 数値入力制限
単価 Leave 原価割れチェック

結局KeyDown、KeyPress、Leaveのイベント登録だけやって、実際のロジックはCellModelっていうクラスに外に出してセルのTagにそのモデルオブジェクトを入れて、イベントに応じて該当の処理が呼ばれるようにした。変えるのはセルのビジネスロジックだけだし。どうせ全部コードビハインドなんだからこれでいいかって思った。

WPFになると、どうもスタイルとイベントを別々に定義できるようだ。WPF Notes: DataGridのセル内で改行にあるように、XAMLで色々出来る。コードビハインドになれると直感的ではないかもしれないけど、ViewModelのコマンドに紐付けられるのなら、すっきりしそうだ。この辺は色々動かして見て学ぶしかないな。

FillWeightプロパティがない

Windows Formではウインドウを最大化するときにFillWeightというプロパティを使うことで、相対的な大きさを設定できる。品番は数量の倍の大きさにするとか、そういうことができた。WPFのDataGridColumn関連には見た所FillWeightがない。Grid全体でColumnWidth="*"にすれば最大化されるけど、どのカラムの等しい大きさになってしまう。

まぁ、明らかにこれ以上大きくする必要がないカラムに対してはMaxWidth設定すればいいかな。

EnterでTabのように次のセルへ進む

Windows Formの場合はDataGridViewでEnterキーを押すと隣のセルにフォーカスが移動されるようにする: .NET Tips: C#, VB.NETでできる。WPFでも考え方は一緒だろう。DataGrid自身のKeyDownを拾ってEnter押されたらTabが押されたことにしてそのイベントを呼び出す、という。

入力項目が多すぎる問題

伝票入力のUIは大きく分けると下記の2つのパターンがある。

  • 入力エリアは別にあって、そこでADDすると下の一覧に追加される
  • 初めから一覧があってExcelのように自分の好きなセルに書き込む

前者のほうが実装は楽。後者だといろんなイベントやコマンドを捕まえないといけないけど、マウスレスで動かすことが出来る。マウスレスなら使いやすいってわけじゃないけどさ。

うーん・・・・前者のUIで1回組んでみようかなぁ・・・。意外といけるんかな?
何のまとまりもない記事ですいません!