- - PR -
ListViewの背景色を変更した時のちらつきを防ぎたい
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2005-09-14 17:18
現在以下のような機能の実装を検討しています。
(1) まず ListView に初期データを投入 (2) データが更新されたら該当するセルのテキストを新データに差し替え (3) データが更新されたことを示すため、一定時間そのセルの背景色を変更する。 (1)と(2)だけに限定すると、データ更新のあった ROW だけがちらつくので、テキストの 差し替えだけなら ROW 単位の再描画が行われるのではないかと思います。 ところが(1)から(3)までを行うと、ListView 全体がちらつきます。ですのでセルの背景色を 変更すると ListView 全体が再描画されているような気がします。 ここで、理想としてはちらつきを完全に抑えたく、それが無理ならセル単位、最低でも ROW 単位でのちらつきに抑えたいのですが、何か良い方法はありますでしょうか。 なお ListView はデータの表形式での表示をさせる上で最も軽量なコントロールだと思って 使用していますが、他に良いコントロールがあればそちらを選択するのに吝かではありません。 よろしくお願い致します。 | ||||
|
投稿日時: 2005-09-14 17:47
ListView.BeginUpdate,EndUpdateメソッドの実行をきちんとしていますか?
[ メッセージ編集済み 編集者: ya 編集日時 2005-09-14 17:49 ] | ||||
|
投稿日時: 2005-09-14 19:13
取りあえず思いついた方法。
こんなのでどうでしょう。 | ||||
|
投稿日時: 2005-09-15 10:31
実行していますが、あまり効果がないようでした。 [ メッセージ編集済み 編集者: kamada 編集日時 2005-09-15 10:31 ] | ||||
|
投稿日時: 2005-09-15 10:34
内容が私には難しいので、しばらく吸収させて下さい。 試してみて結果を後ほどご報告します。 | ||||
|
投稿日時: 2005-09-22 13:08
Hongliangさんのアイデアを元に実装してみました。
環境は.NET 1.1です。 ひとまず実装の簡単そうなRow単位の再描画を試しました。 このリストビューは比較的高い頻度で(秒10回以上)データの更新が起こるのですが、 この実装を入れることにより、ある程度まではRow単位の再描画で済むようなっている ようです。 ただし、約10秒に1度程度のタイミングでList全体の再描画がおきてしまうようです。 (全体再描画のタイミングは一定ではありません) 参考までにこちらで書いたコードを載せますので、なにか指摘があればお願いします。 // //チラつかないListView // public class NonFlickerListView : System.Windows.Forms.ListView { private Rectangle changedBounds = Rectangle.Empty; private const int WM_PAINT = 0x000F; public void ChangeSubItemBackColor(int rowIndex,int columnIndex,Color backColor) { //行全体のBoundsを保持 changedBounds = this.Items[rowIndex].Bounds; //背景色を設定 this.Items[rowIndex].SubItems[columnIndex].BackColor = backColor; } protected override void WndProc(ref Message m) { if(m.Msg == WM_PAINT && changedBounds != Rectangle.Empty) { Rectangle bounds = changedBounds; changedBounds = Rectangle.Empty; ValidateRect(m.HWnd, bounds); Invalidate(bounds); } else { base.WndProc(ref m); } } // Win32 APIのインポート [DllImport( "user32.dll", SetLastError = true )] extern static bool ValidateRect(IntPtr hWnd,Rectangle lpRect); } // //フォーム // public class Form1 : Form { NonFlickerListView myListView; //更新時の処理 void Update() { ..... myListView.ChangeSubItemBackColor(行,列,Color.Red); } } | ||||
|
投稿日時: 2005-09-22 17:08
んー、コードを見てちょっと。
サブアイテム単位での再描画を行うコードを書いてみました。参考にしてみてください。 なお#if !V10 && !V11 から #elseまでは.NET 2.0用のコードなので削除しておいてください(あと#endifの行も)。 | ||||
|
投稿日時: 2005-09-22 17:52
ご指摘ありがとうございます。
連休中に指摘事項を吸収させて頂いて、 休み明けに結果をご報告したいと思います。 |