多列组合框或 DataGridCombo Box 列缩小

Posted

技术标签:

【中文标题】多列组合框或 DataGridCombo Box 列缩小【英文标题】:Multi column combo box or DataGridCombo Box columns shrinking 【发布时间】:2013-03-18 09:34:55 【问题描述】:

我有一个多列组合框。当我第一次使用它时,它工作正常 当我清除它并再次输入数据时,所有列都会缩小,每行只能看到 1-2 个字母。但我想显示文本,例如表格中的所有字母都可见,就像第一张图片一样。

代码:

namespace MultiColumnComboBoxDemo



public class MultiColumnComboBox : ComboBox

    public MultiColumnComboBox()
    
        DrawMode = DrawMode.OwnerDrawVariable;           
    

    public new DrawMode DrawMode
    
        get
        
            return base.DrawMode;
        
        set
        
            if (value != DrawMode.OwnerDrawVariable)
            
                throw new NotSupportedException("Needs to be DrawMode.OwnerDrawVariable");
            
            base.DrawMode = value;
        
    

    public new ComboBoxStyle DropDownStyle
    
        get
        
            return base.DropDownStyle;
        
        set
        
            if (value == ComboBoxStyle.Simple)
            
                throw new NotSupportedException("ComboBoxStyle.Simple not supported");
            
            base.DropDownStyle = value;
        
    

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

        InitializeColumns();
    

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

        InitializeValueMemberColumn();
    

    protected override void OnDropDown(EventArgs e)
    
        base.OnDropDown(e);
        this.DropDownWidth = (int)CalculateTotalWidth();
    

    const int columnPadding = 5;
    private float[] columnWidths = new float[0];
    private String[] columnNames = new String[0];
    private int valueMemberColumnIndex = 0;

    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;
        
    

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

    private float CalculateTotalWidth()
    
        float totWidth = 0;
        foreach (int width in columnWidths)
        
            totWidth += (width + columnPadding);
        
        return totWidth + SystemInformation.VerticalScrollBarWidth;
    

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

        if (DesignMode)
            return;

        for (int colIndex = 0; colIndex < columnNames.Length; colIndex++)
        
            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();

        e.ItemWidth = (int)totWidth;
    

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

        if (DesignMode)
            return;

        e.DrawBackground();

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


            //Shakir
            //using (Pen linePen = new Pen(SystemColors.GrayText))
            using (Pen linePen = new Pen(Color.Black))
            
                using (SolidBrush brush = new SolidBrush(e.ForeColor))
                //using (SolidBrush brush = new SolidBrush(BackColor))
                
                    if (columnNames.Length == 0 && e.Index >=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)
                            
                                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();

    










这是将数据填充到多列组合框中的代码:

SupplierDisplay 是一个数据表 SupplierMaster 是数据库中的表 DBRdRw 是类

SupplierDisplay = DbRdRw.SqlDbRead("Select SupplierID, SupplierName From SupplierMaster", "SupplierMaster");//data filled to a datatable
    //data loading starts
              mcbxSupplier.DataSource = SupplierDisplay;
              mcbxSupplier.ValueMember = "SupplierName";
    mcbxSupplier.DisplayMember = "SupplierName";//ends

【问题讨论】:

【参考方案1】:

当您在 SQL 语句之前重新加载多列组合框时添加一个空表 这是完整的代码

          DataTable dummytable = new DataTable;
          mcbxSupplier.DataSource = dummytable;
          SupplierDisplay = DbRdRw.SqlDbRead("Select SupplierID, SupplierName From SupplierMaster", "SupplierMaster");//data filled to a datatable
          //data loading starts
          mcbxSupplier.DataSource = SupplierDisplay;
          mcbxSupplier.ValueMember = "SupplierName";
          mcbxSupplier.DisplayMember = "SupplierName";//ends

【讨论】:

以上是关于多列组合框或 DataGridCombo Box 列缩小的主要内容,如果未能解决你的问题,请参考以下文章

如何在文本框或组合框中显示多个值

从C#中的WPF组合框或文本框获取文本

如何动态更改 C# 组合框或文本框中的自动完成条目?

打开表单的组合框

聊聊mysql的多列组合查询

子集中所有可能的组合,多列