ちょっと作りたいものがあって、その部品としてTextBoxで項目を編集できるListViewを作りました。 その作り方をメモ。 サンプルコードを実行するとこんなウィンドウが表示されます。
単にListViewにTextBoxを載せたデフォルトの状態だと色々不都合があるのでちょっと手を入れています。
作った環境はこちら。
- Windows7 64bit home
- Visual Studio 2012 Express for Desktop
- .NET Framework 4.5
参考サイトはこちらです。
- kguの日記 ... コントロールテンプレート
- 憂国のプログラマHatena版 ... WPF FAQ Q101. ListBoxItemで子要素の編集時に強調表示するには?
- ざっちのーと ... 【WPF】ListBoxのItemの幅がListBoxの幅にならない
まずはサンプルコードのガワとなる部分を載せましょう。 これを書き換えて目的のコードを作ります。 MainWindow.xamlはこれ。
MainWindow.xaml.csはこれです。
Item.csはこれです。
上のコードをそのまま実行するとTextBoxの幅が入力済みの文字の長さによって変わってしまいます。
これだと不恰好なのでTextBoxの幅を列幅いっぱいに拡大しましょう。
追加したのはListView.ItemContainerStyleの要素です。 実行するとこうなります。
この状態ではTextBoxのフォーカスとListViewの選択行が一致しないという問題があります。
上の画像だと選択行は0行目、TextBoxのフォーカスは2行めです。 ユーザーにとって分かり易い状態ではないので、TextBoxのフォーカスが変更されたらListViewの選択行もそれにあわせて移動するようにしましょう。
Style.Triggers要素を追加しました。 IsKeyboardFocusWithinプロパティは、子コントロールのどれかがキーボードフォーカスを持っていたらtrueになります。 それをトリガーにして選択行を切り替えます。
最後に、TextBoxの枠が表示されるのを選択行だけにしましょう。
追加したのはListView.Resources要素です。 TextBoxのTemplateを指定して、普段のTextBoxは透明な枠の中に文字列を表示するようにしています。 見た目はTextBlockのようになります。 TextBoxをクリックされるなどしてフォーカスが移るとトリガーにひっかかります。 グレーの枠と白の背景色を設定して、TextBoxだと分かる表示に変えます。 見た目は投稿冒頭のキャプチャ画像のとおりです。 これで完成。
最後に、編集後のMainWindow.xaml全体を載せておきます。