- - PR -
ListViewのチェックボックスのみ使用不可にする
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-12-15 17:15
お世話になっております、桜と申します。
現在、VB.NETでListViewを継承したコントロールに、 スクロールは使用可・チェックボックスのみを ユーザ操作不可にしようとしておりますが、苦戦中です。 これまで試したのは、以下のような感じです。 @Enabled = Falseにする ⇒スクロール機能が使えなくなり、NG AItemCheckedイベントで以下の処理を行う If _AfReadOnly = True Then e.NewValue = e.CurrentValue End If ⇒プログラムからもチェック状態を変えられなくなり、NG。 BSetStyleを使用する MyBase.SetStyle(ControlStyles.Selectable, Not Value) MyBase.SetStyle(ControlStyles.UserMouse, Value) MyBase.UpdateStyles() MyBase.RecreateHandle() ⇒効果なし C継承コントロールでやるのをあきらめて、 Panel + ListView + VScrollBarを組み合わせたユーザコントロールで実現する ⇒動作的には実現できたが、既存ソースでのコントロールの置換えが発生するため、 継承でできるのならばやはり継承でやりたい。 Dプログラムからチェック状態を設定する間は、 呼び出し側で必ず読取専用フラグを倒すようにする。 チェック状態の設定が終わったら、再び読取専用フラグを立てる。 ⇒実現可能だが、共通部品の動作としてはイマイチ、ウツクシクない。 何かこの機能について、なにか他の案があればお聞かせいただけますか。 | ||||||||
|
投稿日時: 2005-12-15 17:54
最も、簡単な案 (手抜き?) ですが、
これは呼び出し側でやっているから「ウツクシクない」んです。 元々本来の CheckBox の動きとは異なるのですから、別名のプロパティを定義して、 そこで内部的にフラグを倒してやって変更を適用しては如何でしょうか? _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||
|
投稿日時: 2005-12-15 19:39
じゃんぬねっと様
なるほど。 読み取り専用フラグを倒す処理をコントロール側でやるには、 ListViewItemのCheckedプロパティを継承しないといけないのか?とか思っていましたが、 新しいプロパティORメソッドを用意したほうが早そうですね。 極力既存の呼び出し側ソースにコントロール呼び出し側に手を加えないで、 デザイン画面で読取専用プロパティをTrueにするだけで済ませたいな、 と思っていましたが、この方針が却って手間を増やすだけなら意味ないですね。 その方向で進めてみます。 じゃんぬねっとさん、ありがとうございました。 ちなみに、こんな案もかんがえていました。 (2)の処理に該当コントロールにフォーカスがある場合、という条件を足す。 (前提条件) 初期化時にたまたま該当コントロールにフォーカスがあたってる場合を除けば、 コードからチェックボックスを操作する時には たいていCommandButton等にフォーカスがあたっているだろう. マウスの座標と対象アイテムのエリアが被っているか、等の条件を狭めていけば、 危なっかしいけどまあ何とかなるものになるかも知れない・・・? やっぱり没ですね。動作の保証が賭けになる共通コントロールなんてイヤだし。 | ||||||||
|
投稿日時: 2005-12-15 19:47
新しいプロパティやメソッドを定義したのであれば、既存のソースに置き換えるだけですよね? 置換コマンドを利用すれば、確実にスピーディに置き換えれますから手間じゃないですよ。 漏れが心配であれば、オーバーライドまたは属性を使って、 既存のメソッドやプロパティを隠してしまえば、コンパイル エラーになります。 # あ、継承コントロールになるということは、 # コントロールの型も変えないといけないので無意味ですね。(^-^A)
そうですね。 危なかっしいですし、今後の保守に響いてきそうですのでやめましょう。(^-^;) _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||
|
投稿日時: 2005-12-15 23:38
お世話になります、桜です。
とりあえずこんな感じで、機能的に納得のいくモノができました。 まあ、まださくっと動作確認しただけですが。 全てのメソッドを置き換えるべきかどうかは、ただいま調査中です。 ただ、もともと継承コントロールはあって、そこに機能を追加する形になりますので、 置換えは難しくないと思います。 継承コントロールの中だけを変えて 呼出しを一行たりとも変えたくないという方針にこだわると、 結局却って手間がかかるかも。 だからお勧めいただいた案のほうがよさそうですね。 といいたかったのですが、 分かりづらい文章で失礼いたしました。
| ||||||||
|
投稿日時: 2005-12-21 15:58
お世話になります。桜です。
その後、問題発生&解決したのでご報告を。 似たようなことをやろうと思った人の参考になれば幸いです。 ------------------------------------------------------------------- [問題点] ListViewのItemCheckイベントは、最初に描画を行う際に呼び出される。 そのため、タブコントロールを使ったりしてフォームの起動時に ListViewが隠れていると、ListViewの存在するタブをアクティブにするまで ItemCheckが発生しない。 そのためItemCheckイベントが処理されるときには読取専用フラグがたっており、 画面起動からタブ選択の間に変更した値が無効になる。 これは、Application.DoeventsやMe.Refresh、Me.Updateを行っても同じ。 また、MyBase.OnItemClickを呼び出すとItemClickイベントは走るが、 次にItemClickイベントが走る際のItemClickEventArgs.CurrentValueは、 OnClickを呼ばない場合と同じ。 [回避策] 追加した強制チェックプロパティからの値のセットの際、 強制フラグを追加。 ItemClickが呼び出された際、該当インデックスに強制フラグがたっていたら、 Check状態の変更を有効にする。 -------------------------------------------------------------------------- わざわざ報告するにはベタな回避策だなあ、とは思いつつ、 ItemCheckイベントが最初にコントロールが表示されるまで走らない、というのは 同じような処理をしようと思った人が同じように嵌りそうだとおもったので あえて投稿しておきます。 |
1