2011-08-16 53 views
3

有沒有一種方法可以使SelectedItem的高度大於ListBox中其餘項目的高度?這就是我現在所擁有的,但它只是作爲一個正常的列表框:當DrawMode被OwnerDrawFixed展開列表框中選定的項目高度

public class BuddyListBox : ListBox 
{ 

    public BuddyListBox() 
    { 
     this.ResizeRedraw = true; 
     this.DoubleBuffered = true; 
     this.BorderStyle = BorderStyle.None; 
     this.Dock = DockStyle.Fill; 
     this.DrawMode = DrawMode.OwnerDrawVariable; 
     this.ItemHeight = 16; 
    } 
    protected override void OnDrawItem(DrawItemEventArgs e) 
    { 
     if (e.Index == -1 || e.Index >= this.Items.Count) 
      return; 

     Buddy current = (Buddy)this.Items[e.Index]; 
     //Bitmap icon = current.StatusImage; 

     //e.Graphics.DrawImage(icon, e.Bounds.Left, e.Bounds.Top, 16, 16); 
     e.DrawBackground(); 
     e.Graphics.DrawString(current.Address, e.Font, new SolidBrush(current.Status != BuddyStatus.offline ? e.ForeColor : Color.DarkGray), 16 + e.Bounds.Left, e.Bounds.Top); 
     e.Graphics.DrawString(current.Status.ToString(), e.Font, new SolidBrush(Color.LightGray), e.Bounds.Right - (int)(e.Graphics.MeasureString(current.Status.ToString(), e.Font).Width) - this.Margin.Right, e.Bounds.Top); 
     e.DrawFocusRectangle(); 
    } 

    protected override void OnSelectedIndexChanged(EventArgs e) 
    { 
     this.Refresh(); 
    } 

    protected override void OnMeasureItem(MeasureItemEventArgs e) 
    { 
     if (e.Index == this.SelectedIndex) 
      e.ItemHeight = this.ItemHeight * 2; 
     else 
      e.ItemHeight = this.ItemHeight; 
    } 
} 
+0

this.DrawMode = DrawMode.OwnerDrawFixed; –

+0

我已經嘗試了OwnerDrawFixed和OwnerDrawVariable。 –

回答

6

你OnMeasureItem的沒有做任何事情。將模式更改爲OwnerDrawVariable。

不幸的是,手柄被創建時,MeasureItem事件只發生,所以這裏是一個變通:

public class BuddyListBox : ListBox 
{ 
    int thisIndex = -1; 

    public BuddyListBox() 
    { 
    this.DrawMode = DrawMode.OwnerDrawVariable; 
    } 

    protected override void OnDrawItem(DrawItemEventArgs e) 
    { 
    if (this.Items.Count > 0) 
    { 
     if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) 
     e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds); 
     else 
     e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds); 
     e.Graphics.DrawString(this.Items[e.Index].ToString(), e.Font, Brushes.Black, e.Bounds.Left, e.Bounds.Top); 
     base.OnDrawItem(e); 
    } 
    } 

    protected override void OnSelectedIndexChanged(EventArgs e) 
    { 
    base.OnSelectedIndexChanged(e); 
    thisIndex = this.SelectedIndex; 
    this.RecreateHandle(); 
    } 

    protected override void OnMeasureItem(MeasureItemEventArgs e) 
    { 
    if (e.Index > -1) 
    { 
     if (e.Index == thisIndex) 
     e.ItemHeight = 32; 
     else 
     e.ItemHeight = 16; 
    } 
    base.OnMeasureItem(e); 
    } 
} 
+0

仍然在做同樣的事情... –

+1

@Kevin更新答案與一個工作示例。 MeasureItem事件只發生在控件的句柄被創建時,所以你必須自己調用RecreateHandle。但是,這也暫時將SelectedIndex設置爲-1,因此您還需要一個變量來存儲SelectedIndex值。 – LarsTech

+0

我不確定是否重新創建'Handle'比我的解決方案更昂貴,它通過'Windows API'來設置項目高度,因爲本機ListBox有這個選項,它只是不包含在.Net中。如果使用'Windows API'調用沒有問題,那麼[讀一讀](http://stackoverflow.com/questions/28490543/windows-forms-listbox-with-ownerdrawvariable-bug)。 –

相關問題