zoukankan      html  css  js  c++  java
  • combobox控件实现多列显示

          该程序主要参考codeProject上的一个程序,链接已失去,不过要想其致敬!

        

          默认的combobox是不提供多列显示的,所以这里要用绘制的方法显示该功能,主要是重写combobox。其中combobox有个属性DrawMode,需将其设为DrawMode.OwnerDrawVariable,原因如下:从MSDN摘录.

    Normal 控件中的所有元素都由操作系统绘制,并且元素大小都相等。 
    OwnerDrawFixed 控件中的所有元素都是手动绘制的,并且元素大小都相等。 
    OwnerDrawVariable 控件中的所有元素都由手动绘制,元素大小可能不相等。 

          具体步骤如下:实例以datatable为数据源,数据源也可以是arraylist或通过add()方法添加

             int columnPadding = 5;
            private float[] columnWidths = new float[0];  //项宽度
            private String[] columnNames = new String[0]; //项名称
            private int valueMemberColumnIndex = 0;       //valueMember属性列所在的索引

       /// <summary>
            
    /// 绑定数据源或更改数据源时发生
            
    /// </summary>
            
    /// <param name="e"></param>

            protected override void OnDataSourceChanged(EventArgs e)
            
    {
                
    base.OnDataSourceChanged(e);

                InitializeColumns();
            }



            
    /// <summary>
            
    /// 设置ValueMember属性发生
            
    /// </summary>
            
    /// <param name="e"></param>

            protected override void OnValueMemberChanged(EventArgs e)
            
    {
                
    base.OnValueMemberChanged(e);

                InitializeValueMemberColumn();
            }



            
    /// <summary>
            
    /// 显示下拉框的时候触发
            
    /// </summary>
            
    /// <param name="e"></param>

            protected override void OnDropDown(EventArgs e)
            
    {
                
    base.OnDropDown(e);
                
    this.DropDownWidth = (int)CalculateTotalWidth();  //计算combobox下拉框的总宽度
            }




       
    /// <summary>
            
    /// 初始化数据源各列的名称
            
    /// </summary>

            private void InitializeColumns()
            
    {
                PropertyDescriptorCollection propertyDescriptorCollection 
    = DataManager.GetItemProperties();

                columnWidths 
    = new float[propertyDescriptorCollection.Count];
                columnNames 
    = new String[propertyDescriptorCollection.Count];

                
    for (int colIndex = 0; colIndex < propertyDescriptorCollection.Count; colIndex++)
                
    {
                    String name 
    = propertyDescriptorCollection[colIndex].Name;
                    columnNames[colIndex] 
    = name;
                }

            }



            
    /// <summary>
            
    /// 返回ValueMember在显示列中的索引位置
            
    /// </summary>

            private void InitializeValueMemberColumn()
            
    {
                
    int colIndex = 0;
                
    foreach (String columnName in columnNames)
                
    {
                    
    if (String.Compare(columnName, ValueMember, true, CultureInfo.CurrentUICulture) == 0)
                    
    {
                        valueMemberColumnIndex 
    = colIndex;
                        
    break;
                    }

                    colIndex
    ++;
                }

            }



            
    /// <summary>
            
    /// 计算combobox下拉框的总宽度
            
    /// </summary>
            
    /// <returns></returns>

            private float CalculateTotalWidth()
            
    {

                columnPadding 
    = 5;
                
    float totWidth = 0;
                
    foreach (int width in columnWidths)
                
    {
                    totWidth 
    += (width + columnPadding);
                }


                
    //总宽度加上垂直滚动条的宽度
                return totWidth + SystemInformation.VerticalScrollBarWidth;
            }

    绘制字符串所使用的两个方法:

     /// <summary>
            
    /// 获得各列的宽度和项的总宽度
            
    /// 引发 MeasureItem 事件
            
    /// </summary>
            
    /// <param name="e"></param>

            protected override void OnMeasureItem(MeasureItemEventArgs e)
            
    {
                
    base.OnMeasureItem(e);

                
    if (DesignMode)
                    
    return;

                
    for (int colIndex = 0; colIndex < columnNames.Length; colIndex++)
                
    {
                    
    //如果 ListControl 项是被给定了该项以及属性名称的对象的属性,则返回该项的当前值
                    string item = Convert.ToString(FilterItemOnProperty(Items[e.Index], columnNames[colIndex]));
                    SizeF sizeF 
    = e.Graphics.MeasureString(item, Font);  //返回显示项字符串的大小
                    columnWidths[colIndex] = Math.Max(columnWidths[colIndex], sizeF.Width);
                }


                
    float totWidth = CalculateTotalWidth(); //计算combobox下拉框项宽度

                e.ItemWidth 
    = (int)totWidth;   //设置combobox下拉框项宽度
            }




            
    /// <summary>
            
    /// 绘制下拉框的内容
            
    /// 引发 DrawItem 事件
            
    /// </summary>
            
    /// <param name="e"></param>

            protected override void OnDrawItem(DrawItemEventArgs e)
            
    {
                
    base.OnDrawItem(e);

                
    if (DesignMode)
                    
    return;

                e.DrawBackground();

                Rectangle boundsRect 
    = e.Bounds;
                
    int lastRight = 0;

                
    using (Pen linePen = new Pen(SystemColors.GrayText))
                
    {
                    
    using (SolidBrush brush = new SolidBrush(ForeColor))
                    
    {
                        
    if (columnNames.Length == 0)
                        
    {
                            e.Graphics.DrawString(Convert.ToString(Items[e.Index]), Font, brush, boundsRect);
                        }

                        
    else
                        
    {

                            
    //循环各列
                            for (int colIndex = 0; colIndex < columnNames.Length; colIndex++)
                            
    {
                                
    string item = Convert.ToString(FilterItemOnProperty(Items[e.Index], columnNames[colIndex]));

                                boundsRect.X 
    = lastRight;  //列的左边位置
                                boundsRect.Width = (int)columnWidths[colIndex] + columnPadding; //列的宽度
                                lastRight = boundsRect.Right;

                                
    if (colIndex == valueMemberColumnIndex)//如果是valueMember项
                                {
                                    
    using (Font boldFont = new Font(Font, FontStyle.Bold))
                                    
    {

                                        
    //绘制项的内容
                                        e.Graphics.DrawString(item, boldFont, brush, boundsRect);
                                    }

                                }

                                
    else
                                
    {
                                    
    //绘制项的内容
                                    e.Graphics.DrawString(item, Font, brush, boundsRect);
                                }



                                
    //绘制各项间的竖线
                                if (colIndex < columnNames.Length - 1)
                                
    {
                                    e.Graphics.DrawLine(linePen, boundsRect.Right, boundsRect.Top, boundsRect.Right, boundsRect.Bottom);
                                }

                            }

                        }

                    }

                }


                e.DrawFocusRectangle();
            }

     界面层绑定数据源:

                DataTable dataTable = new DataTable("Employees");

                dataTable.Columns.Add(
    "Employee ID"typeof(String));
                dataTable.Columns.Add(
    "Name"typeof(String));
                dataTable.Columns.Add(
    "Country"typeof(String));
                dataTable.Rows.Add(
    new String[] "1""James""USA" });
                dataTable.Rows.Add(
    new String[] "2""Mary""UK" });
                dataTable.Rows.Add(
    new String[] "3""Jack""Japan" });

          有需要源码的朋友同样可以到我的群中下载.

  • 相关阅读:
    Java进阶学习(5)之设计原则(下)
    Java进阶学习(5)之设计原则(上)
    Java进阶学习(4)之继承与多态(下)
    Java进阶学习(4)之继承与多态(上)
    Java进阶学习(4)之继承与多态.demo
    python自动更新升级失败解决方案
    信息检索
    对卷积神经网络原理理解
    对DensePose: Dense Human Pose Estimation In The Wild的理解
    Java进阶学习(3)之对象容器.小练习
  • 原文地址:https://www.cnblogs.com/gossip/p/1371984.html
Copyright © 2011-2022 走看看