- - PR -
DataGridViewのヘッダーにチェックボックス
投稿者 | 投稿内容 | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2009-02-27 14:08
やり方はわかっていないものの、コントロールの追加で考えていました。 コントロールと同じ機能を実装ということは、イベントの処理なども個別に実装しないといけないのでしょうか?
Paint内に次のコードを記述しました。
また、上記の他に Dim chkBox As CheckBox としてチェックボックス用の変数を用意し、New()の中で chkBox = New CheckBox でインスタンスを作成しています。 以上のコードを記述することによりチェックボックスは表示できましたが 4.headerStrにヘッダーの文字列を入れる方法を教えて下さい 5.cFontにヘッダーのフォントを入れる方法を教えて下さい 6.ヘッダーに元々設定されている文字列と、headerStrの両方が表示されてしまうのでヘッダーに元々設定されている文字列を表示しないようにする方法を教えて下さい 7、チェックボックスの後ろにheaderStrを表示する方法を教えて下さい。 ※結局、チェックボックスを表示する方法を教えて頂く必要がありそうです。 どうも上記のコードはチェックボックスとその文字列がバラバラに表示されているだけで、お互いに関連が無いようです。 チェックボックスの変数(chkBox)は用意したものの、チェックボックスとしては使えていません。 本来はCheckBoxRenderer.DrawCheckBoxでchkBoxを表示するのではないかとぼんやり考えていますがやり方が分からず、ここで止まってしまいました。
コントロールと同じ機能を実装と絡むと思いますが、オーバーライドの仕方を具体的に教えて下さい。 | ||||||||||||||||||||||||||||
|
投稿日時: 2009-02-27 15:38
サンプル作ってみましたので参考にしてください。
下記コードのみでとりあえずなチェックボックスを持つヘッダが実現出来ます。
上記は、単なるチェックボックスがあるヘッダを表示するための最低限必要だと思われるコードです。 したがって、汎用性はありません。(※3ステートチェック未対応だったり、表示位置固定だったり・・・) オーバーライドは[Overrides]修飾子を付けて元関数と同じように宣言することです。 (オーバーライド出来る関数は[Overridable or MustOverride]修飾子がある関数です) 当サンプルでは、Paint,OnClick,OnDoubleClickが該当します。 | ||||||||||||||||||||||||||||
|
投稿日時: 2009-02-27 17:37
お手数をお掛けし申し訳ありません。 大変参考になります。 ありがとうございました。 早速利用させて頂きました。 私はデータ行もチェックボックスで使いたかったので
は
に変更させて頂いたところほぼ期待通りの動きが実現できました。
3ステートチェックもサポートしたいのですが、こちらについてはもう少し調べてみたいと思います。(この後の質問への回答が大きなヒントになることを期待して・・・) 表示位置固定というのはヘッダーの文字列の位置のことだと思いますが、チェックボックスと文字列の間を若干広げたいのでヒントだけでも教えて頂けないでしょうか。 それと、チェックボックスのON/OFFが画面に反映されないのですが修正方法を教えて頂けないでしょうか。 OnClickの中で
の3パターンを試したのですが実行時に「Selected を変更できない」と怒られてしまいました。 試しにMyBase.Value = _checkStateと書いたら、チェックボックスの状態は書き換わるようになりましたが、ヘッダーの文字列も一緒にTrue/Falseと書き換わるようになりました。 チェックボックスの状態を_checkStateと同じ状態にするためにはどのプロパティにアクセスすれば良いのでしょうか? また、クラス内部からヘッダーの文字列にアクセスするにはどうすれば良いのでしょうか ※フォーム側だと「Me.Column1.HeaderText = "CHK"」のようにしてアクセスできることは確認しました。
ありがとうございます。 ということは、フォーム側では通常の使い方と同じだと思い確認のため
と書いてみましたが、どちらのイベントも実行されてしまいました。 DataGridView1_CellClick内でヘッダがクリックされたか否かを判定する方法と、イベント内でヘッダーのチェックボックスの内容を確認する方法を教えて下さい。 [ メッセージ編集済み 編集者: Haru 編集日時 2009-02-27 17:46 ] | ||||||||||||||||||||||||||||
|
投稿日時: 2009-02-27 18:21
以下のコードを書いてみましたがヘッダかどうかの判定はe.RowIndex >= 0で合ってますでしょうか?
[ メッセージ編集済み 編集者: Haru 編集日時 2009-02-27 18:22 ] | ||||||||||||||||||||||||||||
|
投稿日時: 2009-03-02 11:12
提示サンプルコードの各行で何を行っているかを理解してください。
> チェックボックスと文字列の間を若干広げたいのでヒントだけでも チェックボックスのX座標を求めている箇所を修正してください。 location.X = cellBounds.X + (cellBounds.Width - drawTextSize.Width) / 2 - 14 > チェックボックスのON/OFFが画面に反映されないのですが Selected = Me._checkStateやMyBase.Value = _checkStateは どのような意図で記述したのでしょう? DataGridViewColumnHeaderCellのSelectedプロパティは使用不可ですよ。 [MSDN]DataGridViewColumnHeaderCell.Selectedプロパティ リファレンス等をよくみて、各プロパティを理解してください。 > ヘッダーの文字列にアクセスするにはどうすれば ヘッダ文字列の描画は、チェックボックスの描画時に行っています。 System.Windows.Forms.CheckBoxRenderer.DrawCheckBox()の第4引数に formattedValueを渡して、文字列描画しています。 ですので、Value値を変更することで表示文字を変更出来ます。 ※だからMyBase.Value = _checkStateなんてすると、表示文字もTrue/Falseと書き換わるのですよ。 > ヘッダかどうかの判定はe.RowIndex >= 0で合ってますでしょうか? -1:ヘッダ行、0以上:データ行 だと思いますので合ってると思います。 [追記] > イベント内でヘッダーのチェックボックスの内容を確認する方法 例えば、カスタムヘッダセルクラスにチェック状態を返すプロパティを追加します。 CellClickイベントでは、ヘッダセルをカスタムヘッダセルへDirectCastを行い 追加したプロパティを参照することで、チェック状態を取得出来ると思います。 [ メッセージ編集済み 編集者: くまっち 編集日時 2009-03-02 11:32 ] | ||||||||||||||||||||||||||||
|
投稿日時: 2009-03-02 18:37
申し訳ありません。 教えて頂いたコードを理解しようと努めてはいるのですが何分Windowsアプリの作り方について 基礎がほとんどできていないため、調べるポイントが分からずにヘルプを求めてしまいます。
ありがとうございます。 これもAPIを注意深く見れば分かる項目でしたね。 申し訳ありませんでした。
Selectedへ_checkStateをセットしようとしたのは、ヘッダのチェックボックスを ON/OFFしても画面に反映されない(OnClickは実行されることをConsole.WriteLineで確認)ので 自分で設定する必要があるのかと思い追加を試みました。 これについては現在も調査中ですが、OnClick処理の中にブレークポイントを設けると ちゃんと画面にも表示されることからデバッグ文を組み込んで調べてみたところ現在の
ではPaintイベントが発生しない(?)為にヘッダのチェックボックスの状態が変わらないようです。 ※OnClickの中にブレークポイントを設けたり、画面を切り替えたりすると状態が変わります。 試しにMe.RaiseCheckBoxCheckedChanged(EventArgs.Empty)を Me.RaiseCellValueChanged(e)に変えてみたらPaintイベントが発生するようで状態が変更されました。 Paintイベントを発生させるためのコードの追加が必要なのではないでしょうか?
質問の仕方が悪かったようです。 DrawCheckBoxの第4引数がヘッダーの文字列というのはAPIで分かったのですが、Class内で Paintを直接呼び出すコードは書いていないのでクラス内でこの文字列を変更する方法を 知りたかったのです。 もしかして、MyBase.Valueがヘッダの文字列なのでしょうか? ※クラスの構成がよく分かっていません。どこで勉強できますでしょうか?
こんな感じで作成しました。
概ねOKなのですが、Rows(0).Cells(0)のチェックボックスだけは書き換わりません。 何がいけないのでしょうか? | ||||||||||||||||||||||||||||
|
投稿日時: 2009-03-02 20:17
> Paintイベントを発生させるためのコードの追加が必要なのではないでしょうか?
うーん。こちらの提示サンプルでは、チェックボックスヘッダセルをクリックした際 正しく表示更新(Paint実行)されています。 Paintが呼ばれない理由は現時点の情報では特定出来ません。 何かプロパティを規定値以外に設定していたりしてますか? > もしかして、MyBase.Valueがヘッダの文字列なのでしょうか? DataGridViewColumnHeaderCellに関して言えばYesですね。 > Rows(0).Cells(0)のチェックボックスだけは書き換わりません dRow.Cells(0).Value = flag の事でしょうか? 提示されたコードを見た限りでは、何が悪いのか判断出来ません。 デバッガで該当箇所で止め、意図した値になっているか確認してみてください。 | ||||||||||||||||||||||||||||
|
投稿日時: 2009-03-03 11:46
特に何も設定しておりません。
はいそうです。
自分なりにデバッガで確認していますが問題が見つけられておりません。 次のようにボタン押下でも書き換えるようにしてみましたが、同じロジックで ありながら、ボタン押下時とチェックボックス押下時では動作が異なりました。 ボタン押下時は全てのチェックボックスが書き換わりますが、チェックボックス クリック時はRows(0).Cells(0)がスキップされます。 (スキップというのは、元々の値が書き換わらないということです。)
また、先頭に列を追加して一列ずらすと全てのチェックボックスが書き換わります。 今回作成したクラス内でのみRows(0).Cells(0)に特別な意味があるように思えますが 原因が思いつきません。 |