博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

扩展WinForm的ComboBox

Posted on 2008-01-22 14:43  faib  阅读(2373)  评论(7编辑  收藏  举报
    个人认为winform的combobox不是那么的好用,所以自己扩展了一下。
    重新定义Items属性,并且支持树结构。
    为每项加入了CheckBox状态。
    丰富的列表项类ListItem。
    效果如图:
    代码清单:
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace FaibClass.Windows.Forms
{
    [Designer(
typeof(ControlDesigner))]
    
public class ComboBox : System.Windows.Forms.ComboBox
    
{
        
// Fields
        private bool blnIsChange = false;
        
private int m_ImageIndex = -1;
        
private ImageList m_ImageList;
        
private ListItemCollection m_items;
        
private object objSource;
        
private Color m_ItemHoverBackColor;
        
private Color m_ItemHoverGradientBackColor = Color.Empty;
        
private Color m_ItemHoverColor;
        
private int m_Indent = 16;
        
private bool m_CheckBoxes = false;
        
private bool isUpdate = false;
        
private ComboBoxWindow wnd = null;
        
internal static int nextId = 0;

        
Methods

        
Properties

        
ListItemCollection

        
CheckedListItemCollection
        
        
ComboBoxWindow

    }

}


using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Drawing;

namespace FaibClass.Windows.Forms
{
    [Serializable, 
    DesignTimeVisible(
false), 
    DefaultProperty(
"Text"),
    TypeConverter(
typeof(ListItemConverter))]
    
public class ListItem : Component
    
{
        
// Fields
        private int m_ImageIndex = -1;
        
private int m_Index;
        
private object m_Tag;
        
private string m_Text = string.Empty;
        
private object m_Value;
        
private bool m_Checked = false;
        
private Font m_Font;
        
private ComboBox comboBox;
        
private ComboBox.ListItemCollection m_items = new ComboBox.ListItemCollection();
        
private Color m_ForeColor, m_BackColor;
        
private object parent;
        
internal int id = -1;
        
internal int checkboxLeft = -1;
        
internal byte level = 0;

        
// Methods
        public ListItem()
        
{
            
this.m_ImageIndex = -1;
        }


        
public ListItem(string Text) : this (Text, Text, -1)
        
{
        }


        
public ListItem(string Text, int ImageIndex) : this (Text, Text, ImageIndex)
        
{
        }


        
public ListItem(string Text, object Value) : this (Text, Value, -1)
        
{
        }


        
public ListItem(string Text, object Value, int ImageIndex)
        
{
            
this.m_Text = Text;
            
this.m_Value = Value;
            
this.m_ImageIndex = ImageIndex;
        }


        
internal ListItem CloneData()
        
{
            ListItem lt 
= new ListItem();
            lt.Text 
= this.Text;
            lt.ImageIndex 
= this.ImageIndex;
            lt.Font 
= this.Font;
            lt.ForeColor 
= this.ForeColor;
            lt.BackColor 
= this.BackColor;
            lt.Checked 
= this.Checked;
            lt.id 
= id;
            
return lt;
        }


        
public override string ToString()
        
{
            
return this.Text;
        }


        
internal void Host(ComboBox comboBox)
        
{
            
this.comboBox = comboBox;
            m_items.Host(comboBox, 
this);
            m_items.level 
= (byte)(level + 1);
        }


        
Properties
    }

}

using System;
using System.Drawing.Design;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.Reflection;

namespace FaibClass.Windows.Forms
{
    
internal sealed class ListItemConverter: ExpandableObjectConverter
    
{
        
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        
{
            
if(destinationType == typeof(System.ComponentModel.Design.Serialization .InstanceDescriptor))
                
return true;
            
else
                
return base.CanConvertTo (context, destinationType);
        }


        
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        
{
            
if(destinationType ==  typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor))
            
{
                Type valueType 
= value.GetType();
                ConstructorInfo ci 
= valueType.GetConstructor(System.Type.EmptyTypes);
                ListItem item 
= (ListItem)value;
                
return new InstanceDescriptor(ci,null,false);
            }

            
else
                
return base.ConvertTo (context, culture, value, destinationType);
        }
    
    }

}


using System;
using System.Runtime.InteropServices;

namespace FaibClass.Windows.Forms
{
    
internal class Win32
    
{
        [DllImport(
"user32", EntryPoint="GetClientRect")]
        
public static extern int GetClientRect (
            IntPtr hwnd,
            
ref RECT lpRect
            );

        [DllImport(
"user32", EntryPoint="GetWindowRect")]
        
public static extern int GetWindowRect (
            IntPtr hwnd,
            
ref RECT lpRect
            );

        [DllImport(
"user32", EntryPoint="PtInRect")]
        
public static extern int PtInRect (
            
ref RECT lpRect,
            
ref POINTAPI pt
            );

        [DllImport(
"user32", EntryPoint="SendMessage")]
        
public static extern int SendMessage (
            IntPtr hwnd,
            
int wMsg,
            
int wParam,
            
int lParam
            );

        [DllImport(
"user32", EntryPoint="SendMessage")]
        
public static extern int SendMessage (
            IntPtr hwnd,
            
int wMsg,
            
int wParam,
            
ref RECT rect
            );

        [DllImport(
"user32", EntryPoint="InvalidateRect")]
        
public static extern int InvalidateRect (
            IntPtr hwnd,
            RECT lpRect,
            
int bErase
            );

        [StructLayout(LayoutKind.Sequential)]
        
public struct RECT  
        
{
            
public int Left;
            
public int Top;
            
public int Right;
            
public int Bottom;
        }

        [StructLayout(LayoutKind.Sequential)]
        
public struct POINTAPI  
        
{
            
public int x;
            
public int y;
        }


        
public static int HIWORD(int lparam)
        
{
             
return ((lparam >> 16& 0xffff);
        }


        
public static int LOWORD(int lparam)
        
{
            
return (lparam & 0xffff);
        }


        
public static int MakeLParam(int LoWord, int HiWord)
        
{
            
return (HiWord << 16| (LoWord & 0xffff);
        }



    }

}