2009-08-10 51 views

回答

0

您將需要實現一個自繪的ListBox。我有一個顯示所有項目的圖標和複選框,但是您可以輕鬆修改它以僅顯示特定項目的複選框。

public class IconizedCheckedListBox : ListBox 
{ 
    public IconizedCheckedListBox() 
     : base() 
    { 
     DrawMode = DrawMode.OwnerDrawVariable; 
     DoubleBuffered = true; 
    } 

    protected override void OnDrawItem(DrawItemEventArgs e) 
    { 
     Graphics g = e.Graphics; 
     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 


     using (SolidBrush b = new SolidBrush(BackColor)) 
      g.FillRectangle(b, e.Bounds); 

     //e.DrawBackground(); 
     //e.DrawFocusRectangle(); 

     if (e.Index < Items.Count && e.Index != -1) 
     { 
      IconizedCheckedListBoxItem item = (IconizedCheckedListBoxItem)Items[e.Index]; 

      Rectangle checkBounds = e.Bounds; 
      checkBounds.X += kCheckboxPadding; 
      checkBounds.Y += (checkBounds.Height - kCheckboxSize)/2; 
      checkBounds.Width = kCheckboxSize; 
      checkBounds.Height = kCheckboxSize; 
      CheckBoxRenderer.DrawCheckBox(g, checkBounds.Location, 
       item.Checked?CheckBoxState.CheckedNormal:CheckBoxState.UncheckedNormal); 

      using (SolidBrush b = new SolidBrush(ForeColor)) 
      { 
       StringFormat format = new StringFormat(); 
       format.LineAlignment = StringAlignment.Center; 
       format.Alignment = StringAlignment.Near; 
       Rectangle textBounds = e.Bounds; 
       textBounds.X += item.Icon.Width + 2*kCheckboxPadding + kCheckboxSize; 
       textBounds.Y += 1; 
       textBounds.Width -= item.Icon.Width; 
       textBounds.Height -= 1; 
       Font f; 
       if (item.Checked) 
        f = new Font(Font, FontStyle.Bold); 
       else 
        f = Font; 
       g.DrawString(item.Data.ToString(), f, b, textBounds, format); 
      } 

      Image icon; 
      if (!item.Checked) 
       icon = Utilities.Utilities.WashOutImage(item.Icon); 
      else 
       icon = item.Icon; 
      g.DrawImage(icon, e.Bounds.X + 2 * kCheckboxPadding + kCheckboxSize, e.Bounds.Y); 
     } 
    } 

    protected override void OnMeasureItem(MeasureItemEventArgs e) 
    { 
     e.ItemHeight = kItemHeight; 
    } 

    protected override void OnMouseClick(MouseEventArgs e) 
    { 
     if (e.Button == MouseButtons.Left) 
     { 
      int idx = IndexFromPoint(e.Location); 
      if (idx != -1) 
      { 
       IconizedCheckedListBoxItem item = (IconizedCheckedListBoxItem)Items[idx]; 
       item.Checked = !item.Checked; 

       if (ItemCheck != null) 
       { 
        ItemCheckEventArgs args = new ItemCheckEventArgs(
         idx, 
         item.Checked ? CheckState.Checked : CheckState.Unchecked, 
         CheckState.Indeterminate); 
        ItemCheck(this, args); 
       } 
       Invalidate(); 
      } 
     } 
     base.OnMouseClick(e); 
    } 

    /// <summary> 
    /// This is called AFTER the check state has been updated 
    /// </summary> 
    public event ItemCheckEventHandler ItemCheck; 

    private const int kItemHeight = 32; 
    private const int kCheckboxSize = 13; 
    private const int kCheckboxPadding = 4; 
} 

public class IconizedCheckedListBoxItem 
{ 
    public IconizedCheckedListBoxItem(Image inIcon, object inData) 
    { 
     Icon = inIcon; 
     Data = inData; 
     Checked = false; 
    } 

    public override string ToString() 
    { 
     return Data.ToString(); 
    } 

    public Image Icon; 
    public object Data; 
    public bool Checked; 
} 
+1

OP要求提供「ListView」而不是「ListBox」。這不是一個有效的答案。 – Nick 2009-10-20 22:34:49

1

那些行標題?如果是這樣,請考慮在您的ListView中使用Groups

編輯:

我不知道的任何方式,只會顯示在列表視圖的項目子集的複選框。另一種方法是設置要灰色的項目的ForeColor,並在ItemCheck事件中重置這些項目的檢查狀態,如果它們被選中則取消選中。

+1

沒有行不是標題這只是不應該被選中的行。客戶希望複選框被隱藏 – zidane 2009-08-10 14:35:09