2012-04-28 86 views
18

TreeView.BeginUpdateを追加するとツリービューのちらつきが防止されることがわかりましたが、ツリービューのすべてのノードが表示されなくなったときに、何が起こるのか教えてください。ここでコードスニペット使用TreeView.BeginUpdateとTreeView.EndUpdateツリービューがちらつきますか?

TreeNode treeNode = new TreeNode("Windows"); 
     treeView1.Nodes.Add(treeNode); 
     // 
     // Another node following the first node. 
     // 
     treeNode = new TreeNode("Linux"); 
     treeView1.Nodes.Add(treeNode); 
     // 
     // Create two child nodes and put them in an array. 
     // ... Add the third node, and specify these as its children. 
     // 
     TreeNode node2 = new TreeNode("C#"); 
     TreeNode node3 = new TreeNode("VB.NET"); 
     TreeNode[] array = new TreeNode[] { node2, node3 }; 
     // 
     // Final node. 
     // 
     treeNode = new TreeNode("Dot Net Perls", array); 
     treeView1.Nodes.Add(treeNode); 
+6

一つ目は右見ていないこと - あなたは 'BeginUpdate' /'ループ内EndUpdate'やっている - と悪いことを、 'EndUpdate'は、いくつかの条件コードの中にネストされた - 私は普通に期待疑わしいコードにもかかわらず、視覚的な更新を抑制して、更新のセット全体をラップするようにしてください(第2の例では –

+0

)。問題の症状を改善しようとしているようです。なぜあなたは最初にちらつくのですか?またはちらつきがありませんでしたか? –

+0

ノードの追加の直前で使用した場合は、(.Nodes.Add)という意味で十分でしょうか? – vettori

答えて

60

開始/ EndUpdateメソッド()メソッドは、フリッカを排除するように設計ないました。 EndUpdate()でフリッカーを取得することは避けられず、コントロールを再描画します。それらは、大量のノードの追加を高速化するように設計されています。これは、単一のアイテムごとに再描画が行われるため、デフォルトでは遅くなります。あなたはそれをforループの中に入れて、すぐに改善のために外側に移動させることで、それをさらに悪化させました。

おそらく問題を解決するのに十分でしょう。しかし、ちらつきを抑えるにはダブルバッファリングが必要です。 .NET TreeViewクラスはDoubleBufferedプロパティをオーバーライドし、を隠します。歴史的事故であるネイティブのWindowsコントロールは、Windows XP以降ではダブルバッファリングしかサポートしていません。 .NETはかつてWindows 2000とWindows 98をサポートしていました。

最近、これはもうあまり関係ありません。 TreeViewから独自のクラスを派生させることで、それを戻すことができます。プロジェクトに新しいクラスを追加し、以下に示すコードを貼り付けます。コンパイル。既存のTreeViewを置き換える、ツールボックスの上部から新しいコントロールをフォームにドロップします。効果は、特にスクロールするときに非常に顕著です。

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

class BufferedTreeView : TreeView { 
    protected override void OnHandleCreated(EventArgs e) { 
     SendMessage(this.Handle, TVM_SETEXTENDEDSTYLE, (IntPtr)TVS_EX_DOUBLEBUFFER, (IntPtr)TVS_EX_DOUBLEBUFFER); 
     base.OnHandleCreated(e); 
    } 
    // Pinvoke: 
    private const int TVM_SETEXTENDEDSTYLE = 0x1100 + 44; 
    private const int TVM_GETEXTENDEDSTYLE = 0x1100 + 45; 
    private const int TVS_EX_DOUBLEBUFFER = 0x0004; 
    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 
} 
+5

MSDNでは、TVM_SETEXTENDEDSTYLEの使用が正しくないことを示唆しています。 http://msdn.microsoft.com/en-us/library/windows/desktop/bb773744(v=vs.85).aspxでWPARAMはマスクで、LPARAMはフラグです。だから、古いスタイルをスキップし、SendMessage(this.Handle、TVM_SETEXTENDEDSTYLE、(IntPtr)TVS_EX_DOUBLEBUFFER、(IntPtr)TVS_EX_DOUBLEBUFFER)を実行してください。 – EricLaw

+0

確かに。私はこれを間違って文書化するMSDNライブラリの古いコピーを使用しています。正しいことをありがとう! –

関連する問題