代码改变世界

扩展WinForm的ComboBox

  观海看云  阅读(494)  评论(0编辑  收藏  举报
个人认为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
    


        
#endregion


        
CheckedListItemCollection CheckedListItemCollection
        
public class CheckedListItemCollection : CollectionBase
        
{
            
public void Add(ListItem item)
            
{
                List.Add(item);
            }


            
public void Remove(ListItem item)
            
{    
                List.Remove(item);
            }


            
public ListItem this[int index]
            
{
                
get{
                    
if(index < 0 || index > List.Count - 1)
                        
throw new ArgumentNullException("索引值超出集合的范围");
                    
return List[index] as ListItem;
                }

            }

        }

        
#endregion
        
        
ComboBoxWindow ComboBoxWindow
        
internal class ComboBoxWindow : NativeWindow
        
{
            
private System.Windows.Forms.ComboBox.ObjectCollection items;
            
private IntPtr handle = IntPtr.Zero;

            
internal ComboBoxWindow(System.Windows.Forms.ComboBox.ObjectCollection items, IntPtr handle)
            
{
                
this.items = items;
                
this.handle = handle;
            }


            
protected override void WndProc(ref Message m)
            
{
                
if(m.Msg == 0x201)//WM_LBUTTONDOWN
                {
                    Win32.RECT rect 
= new Win32.RECT();
                    Win32.GetClientRect(m.HWnd, 
ref rect);
                    Win32.POINTAPI pt 
= new Win32.POINTAPI();
                    pt.x 
= Win32.LOWORD(m.LParam.ToInt32());
                    pt.y 
= Win32.HIWORD(m.LParam.ToInt32());
                    
//如果在区域内
                    if(new Rectangle(rect.Left, rect.Top,rect.Left + rect.Right, rect.Top + rect.Bottom).Contains(new Point(pt.x, pt.y)))
                    
{
                        
int nItemHeight = Win32.SendMessage(m.HWnd, 0x1A100);//LB_GETITEMHEIGHT
                        
//获得顶部项的索引
                        int nTopIndex = Win32.SendMessage(m.HWnd, 0x18E00); //LB_GETTOPINDEX
                        int nIndex = nTopIndex + pt.y / nItemHeight;
                        
if (items.Count == 0)
                        
{
                            
base.WndProc (ref m);
                            
return;
                        }

                        
//判断是否在复选框处
                        if(pt.x > ((ListItem)items[nIndex]).checkboxLeft && pt.x < ((ListItem)items[nIndex]).checkboxLeft + 16)
                        
{
                            Win32.RECT re 
= new Win32.RECT();
                            
//取位置
                            Win32.SendMessage(m.HWnd, 0x198, nIndex, ref re); //LB_GETITEMRECT
                            
//重画
                            Win32.InvalidateRect(m.HWnd, re, 0);
                            
//发送自定消息勾选复选框
                            Win32.SendMessage(handle, 0x400 + 0x105, nIndex, 0);
                            
return;
                        }

                    }

                }

                
base.WndProc (ref m);
            }

        }

        
#endregion

    }

}


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


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


using System;
using System.Runtime.InteropServices;

namespace FaibClass.Windows.Forms

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
点击右上角即可分享
微信分享提示