2010-07-23 105 views
0

我有一個ownerrawn列表框太頻繁重繪的代碼。它似乎與嘗試滾動事件的高度不同於正常高度有關。瞭解ownerdrawn listbox + OwnerDrawVariable屬性

這裏是一個可以粘貼到空白的形式「來重現問題最小碼」(擦除設計師文件) - VB版(當然是C#中做同樣的事情):

Public Class Form1 
    Inherits System.Windows.Forms.Form 
    Friend WithEvents ListBox1 As New System.Windows.Forms.ListBox 

    Private Sub ListBox1_DrawItem(ByVal sender As Object, ByVal e As _ 
            System.Windows.Forms.DrawItemEventArgs) Handles ListBox1.DrawItem 
     If e.Index = -1 Then Exit Sub 
     Dim i As Integer = CType(ListBox1.Items(e.Index), Integer) 
     e.DrawBackground() 
     If i Mod 4 <> 0 Then 
      e.Graphics.DrawString("Item #: " & i.ToString & Space(20).Replace(" ", " <Filler>"), _ 
            ListBox1.Font, Brushes.Black, 0, e.Bounds.Top) 
     Else 
      e.Graphics.DrawLine(Pens.Blue, 10, e.Bounds.Top + 1, 52, e.Bounds.Top + 1) 
     End If 
     e.DrawFocusRectangle() 
    End Sub 

    Private Sub ListBox1_MeasureItem(ByVal sender As Object, ByVal e As _ 
        System.Windows.Forms.MeasureItemEventArgs) Handles ListBox1.MeasureItem 
     If e.Index = -1 Then Exit Sub 
     If CInt(ListBox1.Items(e.Index)) Mod 4 = 0 Then 
      e.ItemHeight = 2 
     End If 
    End Sub 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As _ 
          System.EventArgs) Handles MyBase.Load 

     Me.ListBox1.Dock = System.Windows.Forms.DockStyle.Fill 
     Me.ListBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable 
     Me.ClientSize = New System.Drawing.Size(454, 899) 
     Me.Controls.Add(Me.ListBox1) 

     For i As Integer = 0 To 500 
      ListBox1.Items.Add(i) 
     Next 
    End Sub 
End Class 

的ownerdrawn listbox繪製好,但我有一個應用程序使用這種風格的列表框,它是一個宏回放。

您可以選擇一個開始位置,然後單擊單步或「自動播放」。當然,宏正在播放列表框。當它開始滾動時,會像瘋狂的一樣閃爍,當它觸及的非標準尺寸的物品時會重新粉刷。

嘗試在縮小的版本中滾動,以複製問題 - 通過滾動條,或只是躺在向下的箭頭上。

任何想法我做錯了 - 而不必徹底改造列表框?非常感激。 (我重申了這個問題,使其更清晰)。

回答

1

blog有一個解決方案,可能的幫助。它在C#中。看起來好像重寫OnPaint可能是一條路。

+0

那個博客有答案,謝謝。我鞠躬 - 我的google-fu很好,你的更好。 – FastAl 2010-08-23 18:34:00

1

我重新創建你的程序在C#.NET中的3.5和.NET 2.0,我不知道我應該是什麼能夠看到 - 有一個有時有點閃爍,但沒有那麼糟糕

這裏該方案在行動視頻:
http://pixetell.com/p00148Ce5hdFxqn78wII8FrtMRK1Hy8f1D84KE7McLQgvrU9l35

public class Form1 : System.Windows.Forms.Form 
{ 
    System.Windows.Forms.ListBox ListBox1 = new System.Windows.Forms.ListBox(); 

    public Form1() : base() 
    { 
     this.Load += new System.EventHandler(Form1_Load); 

     ListBox1.DrawItem+=new System.Windows.Forms.DrawItemEventHandler(ListBox1_DrawItem); 
     ListBox1.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(ListBox1_MeasureItem); 
    } 

    private void ListBox1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) 
    { 
     if (e.Index == -1) 
      return; 

     int i = System.Convert.ToInt32(ListBox1.Items[e.Index]); 

     e.DrawBackground(); 

     if (i % 4 != 0) 
     { 
      string spaces = new string(' ', 20); 

      e.Graphics.DrawString(
       "Item #: " + i.ToString() + spaces.Replace(" ", " <Filler>"), 
        ListBox1.Font, 
        System.Drawing.Brushes.Black, 
        0, 
        e.Bounds.Top); 
     } 
     else 
     { 
      e.Graphics.DrawLine(
       System.Drawing.Pens.Blue, 
       10, 
       e.Bounds.Top + 1, 
       52, 
       e.Bounds.Top + 1); 
     } 

     e.DrawFocusRectangle(); 
    } 

    private void ListBox1_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e) 
    { 
     if (e.Index == -1) 
      return; 

     if ((System.Convert.ToInt32(ListBox1.Items[e.Index]) % 4) == 0) 
     { 
      e.ItemHeight = 2; 
     } 
    } 

    private void Form1_Load(object sender, System.EventArgs e) 
    { 
     ListBox1.Dock = System.Windows.Forms.DockStyle.Fill; 
     ListBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable; 

     ClientSize = new System.Drawing.Size(454, 899); 
     Controls.Add(ListBox1); 

     for (int i = 0; i < 500; i++) 
     { 
      ListBox1.Items.Add(i); 
     } 

     ListBox1.Visible = true; 
    } 
} 
0

這個答案可能有點晚,但爲什麼不使用BeginUpdate()和EndUpdate()。

+1

Thx爲您的答案,但問題是當系統決定重新列表,而不是當我。項目已經可以添加了,並且根據其他窗口中經常發生的情況,所有者繪製的所有內容都會像瘋了一樣閃爍(特別是如果2個應用程序使用ownerdrawn列表框)。 – FastAl 2011-10-04 16:48:50