[C#.NET][Winform] 具有圖形選項的 ComboBox

  • 12741
  • 0
  • 2013-08-16

[C#.NET][Winform] 具有圖形選項的 ComboBox

本篇主要是利用Pen類別來畫框框,然後把框框用Graphics.FillRectangle方法填滿,Graphics.DrawString方法寫出顏色名稱,來達成下列效果。

image

1.首先若是要使用自己定義的下拉式選單要先設定 DrawMode 屬性為OwnerDraw系列…

this.comboBox1.DrawMode = DrawMode.OwnerDrawVariable;

 

2.再來,將顏色加入到ComboBox.Items屬性裡面,我反射靜態屬性將顏色列舉出來並加入到ComboBox裡,在這裡我用了Color以及SolidBrush類別。

private void Form1_Load(object sender, EventArgs e)
{
    this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
    this.comboBox1.DrawMode = DrawMode.OwnerDrawVariable;
    this.comboBox2.DropDownStyle = ComboBoxStyle.DropDownList;
    this.comboBox2.DrawMode = DrawMode.OwnerDrawVariable; 

    List<SolidBrush> brush = GetBrushes();
    List<Color> color = GetColor();
    foreach (var item in brush)
    {
        this.comboBox1.Items.Add(item);
    }
    foreach (var item in color)
    {
        this.comboBox2.Items.Add(item);
    }
} 

List<SolidBrush> GetBrushes()
{
    Type type = typeof(Brushes);
    List<SolidBrush> brushs = new List<SolidBrush>();
    BindingFlags flags = (BindingFlags.Public | BindingFlags.Static);
    foreach (MemberInfo info in type.GetMembers(flags))
    {
        if (info.MemberType == MemberTypes.Property)
        {
            string name = info.Name;
            //靜態屬性
            object obj = type.GetProperty(name).GetValue(null, null);
            brushs.Add((SolidBrush)obj);
        }
    }
    return brushs;
}
List<Color> GetColor()
{
    Type type = typeof(Color);
    List<Color> colors = new List<Color>();
    BindingFlags flags = (BindingFlags.Public | BindingFlags.Static);
    foreach (MemberInfo info in type.GetMembers(flags))
    {
        if (info.MemberType == MemberTypes.Property)
        {
            string name = info.Name;
            //靜態屬性
            object obj = type.GetProperty(name).GetValue(null, null);
            colors.Add((Color)obj);
        }
    }
    return colors;
}

 

 

3.重繪下拉式選單,利用ComboBox.DrawItem事件重新畫出來,裡面的座標、大小都是用try的,try出我覺得看起來還ok的位置,我開發的系統是winxp,或許在別的系統這些座標又不適用了

private void comboBox_DrawItem(object sender, DrawItemEventArgs e)
{
    if (e.Index == -1)
        return;
    if (sender == null)
        return;
    ComboBox comboBox = (ComboBox)sender;
    Graphics graphics = e.Graphics;
    //取出ComboBox裡的顏色
    SolidBrush brush = null;//建立筆刷
    if (comboBox.Items[e.Index] is SolidBrush)
    {
        brush = (SolidBrush)comboBox.Items[e.Index];
    }
    else if (comboBox.Items[e.Index] is Color)
    {
        brush = new SolidBrush((Color)comboBox.Items[e.Index]);
    }
    //畫出預覽框,用黑色
    Rectangle rect = e.Bounds;
    rect.Offset(1, 1);
    rect.Width = 50;
    rect.Height -= 4;
    graphics.DrawRectangle(new Pen(Color.Black), rect);
    //將顏色填入預覽框,為了不讓黑色框框被蓋到,填顏色時需要調一下位置跟大小
    rect.Offset(1, 1);
    rect.Width -= 1;
    rect.Height -= 1;
    graphics.FillRectangle(brush, rect);
    //畫出顏色名稱,用黑色寫字,定義其位置
    graphics.DrawString(brush.Color.Name.ToString(), e.Font, new SolidBrush(Color.Black), e.Bounds.X + 60, e.Bounds.Y + 3);
}

 

 

4.最後,當ComboBox被選中了,則把選中的顏色畫出來,我使用ComboBox.SelectedIndexChanged事件,來決定哪個選項被選中。

private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    if (sender == null)
        return;
    ComboBox comboBox = (ComboBox)sender;
    SolidBrush brush = null;
    if (comboBox.SelectedItem is SolidBrush)
    {
        brush = (SolidBrush)comboBox.SelectedItem;
        this.panel1.BackColor = brush.Color;
    }
    else if (comboBox.SelectedItem is Color)
    {
        brush = new SolidBrush((Color)comboBox.SelectedItem);
        this.panel2.BackColor = brush.Color;
    }
}

 

執行結果如下:ComboBox_DrawItem.zip

image

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo