WinForms组合框有多列(C#)?

时间:2009-07-07 09:58:51

标签: c# winforms combobox

我目前使用以下代码填充组合框:

combobox.DataSource = datatable;
combobox.DisplayMember = "Auftragsnummer";
combobox.ValueMember = "ID";

有没有办法显示多个列。我为DisplayMember尝试了“Auftragsnummer,Kunde,Beschreibung”,但它没有用。

11 个答案:

答案 0 :(得分:12)

您不能拥有多个列。虽然您可以将多个字段连接为显示成员

退房: How do I bind a Combo so the displaymember is concat of 2 fields of source datatable?

答案 1 :(得分:9)

MSDN上有一篇文章描述了如何创建Multicolumn ComboBox。

  

如何为组合框创建多列下拉列表   Windows窗体

http://support.microsoft.com/kb/982498


来自上面的Microsoft Link的VB下载的源代码,可以很容易地适应ListBox和ComboBox:

'************************************* Module Header **************************************'
' Module Name:  MainForm.vb
' Project:      VBWinFormMultipleColumnComboBox
' Copyright (c) Microsoft Corporation.
' 
' 
' This sample demonstrates how to display multiple columns of data in the dropdown of a ComboBox.
' 
' This source is subject to the Microsoft Public License.
' See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
' All other rights reserved.
' 
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
' EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
' WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
'******************************************************************************************'

Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Imports System.Drawing.Drawing2D

Public Class MainForm

    Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim dtTest As DataTable = New DataTable()
        dtTest.Columns.Add("ID", GetType(Integer))
        dtTest.Columns.Add("Name", GetType(String))

        dtTest.Rows.Add(1, "John")
        dtTest.Rows.Add(2, "Amy")
        dtTest.Rows.Add(3, "Tony")
        dtTest.Rows.Add(4, "Bruce")
        dtTest.Rows.Add(5, "Allen")

        ' Bind the ComboBox to the DataTable
        Me.comboBox1.DataSource = dtTest
        Me.comboBox1.DisplayMember = "Name"
        Me.comboBox1.ValueMember = "ID"

        ' Enable the owner draw on the ComboBox.
        Me.comboBox1.DrawMode = DrawMode.OwnerDrawFixed
        ' Handle the DrawItem event to draw the items.
    End Sub

    Private Sub comboBox1_DrawItem(ByVal sender As System.Object, _
                                   ByVal e As System.Windows.Forms.DrawItemEventArgs) _
                                   Handles comboBox1.DrawItem
        ' Draw the default background
        e.DrawBackground()

        ' The ComboBox is bound to a DataTable,
        ' so the items are DataRowView objects.
        Dim drv As DataRowView = CType(comboBox1.Items(e.Index), DataRowView)

        ' Retrieve the value of each column.
        Dim id As Integer = drv("ID").ToString()
        Dim name As String = drv("Name").ToString()

        ' Get the bounds for the first column
        Dim r1 As Rectangle = e.Bounds
        r1.Width = r1.Width / 2

        ' Draw the text on the first column
        Using sb As SolidBrush = New SolidBrush(e.ForeColor)
            e.Graphics.DrawString(id, e.Font, sb, r1)
        End Using

        ' Draw a line to isolate the columns 
        Using p As Pen = New Pen(Color.Black)
            e.Graphics.DrawLine(p, r1.Right, 0, r1.Right, r1.Bottom)
        End Using

        ' Get the bounds for the second column
        Dim r2 As Rectangle = e.Bounds
        r2.X = e.Bounds.Width / 2
        r2.Width = r2.Width / 2

        ' Draw the text on the second column
        Using sb As SolidBrush = New SolidBrush(e.ForeColor)
            e.Graphics.DrawString(name, e.Font, sb, r2)
        End Using
    End Sub
End Class

答案 2 :(得分:5)

您可以在数据集中添加一个虚拟列(Description),并在组合框数据绑定中将其用作DisplayMember

SELECT Users.*, Surname+' '+Name+' - '+UserRole AS Description FROM Users
ComboBox.DataBindings.Add(new Binding("SelectedValue", bs, "ID"));
ComboBox.DataSource = ds.Tables["Users"];
ComboBox.DisplayMember = "Description";
ComboBox.ValueMember = "ID";

简单而有效。

答案 3 :(得分:3)

它在.NET中无法开箱即用(无论是Windows窗体还是asp.net的下拉列表) 查看此代码项目项目,以获取有关如何构建自己的项目项目的参考。 (虽然有更多的负载)。

Code Project

答案 4 :(得分:2)

有一篇关于Code Project的文章描述了如何创建Multicolumn ComboBox。

Multicolumn Combobox - Code Project

答案 5 :(得分:1)

这是我从Visual Basic转换而来的C#的完整解决方案。

过去8年来我一直在使用它。请注意,日期格式适用于非美国用户。

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Windows.Forms;

namespace MultiColumnCombcs
{
    public partial class MultiColumnCombocs: ComboBox
    {
    // Hide some properties
    [Browsable(false)]
    public new bool IntegralHeight { get; set; }

    [Browsable(false)]
    public new DrawMode DrawMode { get; set; }

    [Browsable(false)]
    public new int DropDownHeight { get; set; }

    [Browsable(false)]
    public new ComboBoxStyle DropDownStyle { get; set; }

    [Browsable(false)]
    public new bool DoubleBuffered { get; set; }

    public Boolean paintHandled = false;
    public const int WM_PAINT = 0xF;
    public int intScreenMagnification = 125; // Screen Magnification = 125%
    // Dropdown
    private string _columnWidths;
    private string[] columnWidthsArray;

    // 'Combo Box
    private Color _buttonColor = Color.Gainsboro;
    private Color _borderColor = Color.Gainsboro;
    private readonly Color bgSelectedColor = Color.PaleGreen; 
    private readonly Color textselectedcolor = Color.Red;
    private readonly Color bgColor = Color.White;
    private readonly Color lineColor = Color.White;
   
    private Brush backgroundBrush = new SolidBrush(SystemColors.ControlText);
    private Brush arrowBrush = new SolidBrush(Color.Black);
    private Brush ButtonBrush = new SolidBrush(Color.Gainsboro);

    //Properties
    [Browsable(true)]
    public Color ButtonColor
    {
        get
        {
            return _buttonColor;
        }
        set
        {
            _buttonColor = value;
            ButtonBrush = new SolidBrush(this.ButtonColor);
            this.Invalidate();
        }
    }

    [Browsable(true)]
    public Color BorderColor
    {
        get
        {
            return _borderColor;
        }
        set
        {
            _borderColor = value;
            this.Invalidate();
        }
    }
    //Column Widths to be set in Properties Window as string containing width of each column in Pixels, 
    // delimited by ';' eg 15;45;40;100,50;40 for six columns

    [Browsable(true)]
    public string ColumnWidths 
    {
        get
        {
        if (string.IsNullOrEmpty(_columnWidths))
            {
                _columnWidths = "15";  //default value
            }

            return _columnWidths;
        }
        set
        {
            _columnWidths = value;
            // split Column Widths string into Array of substrings delimited by ';' character
            columnWidthsArray = _columnWidths.Split(System.Convert.ToChar(";")); 
            int w = 0;
            foreach (string str in columnWidthsArray)
                w += System.Convert.ToInt32(System.Convert.ToInt32(str) * intScreenMagnification / 100);// ******
            DropDownWidth = (w + 20);
        }
    }

    // Constructor stuff
    public MultiColumnCombocs() : base()
    {
        base.IntegralHeight = false;
        base.DrawMode = DrawMode.OwnerDrawFixed;
        base.DropDownStyle = ComboBoxStyle.DropDown;
        MaxDropDownItems = 12;
        // Minimise flicker in painted control
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    }

    protected override void WndProc(ref Message m)  // Listen for operating system messages
    {   
        base.WndProc(ref m);  /*Inheriting controls should call the base class's WndProc(Message) method
                                to process any messages that they do not handle.*/
        switch (m.Msg)
        {
            case WM_PAINT:
                // Draw Combobox and dropdown arrow
                Graphics g = this.CreateGraphics();
                // Background - Only the borders will show up because the edit box will be overlayed
                try
                {
                    backgroundBrush = new SolidBrush(Color.White);
                    g.FillRectangle(backgroundBrush, 0, 0, Size.Width, Size.Height);
                    // Border
                    Rectangle rectangle = new Rectangle();
                    Pen pen = new Pen(BorderColor, 2);
                    rectangle.Size = new Size(Width - 2, Height);
                    g.DrawRectangle(pen, rectangle);
                    
                    // Background of the dropdown button
                    ButtonBrush = new SolidBrush(ButtonColor);
                    Rectangle rect = new Rectangle(Width - 15, 0, 15, Height);
                    g.FillRectangle(ButtonBrush, rect);

                    // Create the path for the arrow
                    g.SmoothingMode = SmoothingMode.AntiAlias;

                    GraphicsPath pth = new GraphicsPath();
                    PointF TopLeft = new PointF(Width - 12, System.Convert.ToSingle((Height - 5) / 2));
                    PointF TopRight = new PointF(Width - 5, System.Convert.ToSingle((Height - 5) / 2));
                    PointF Bottom = new PointF(Width - 8, System.Convert.ToSingle((Height + 4) / 2));
                    pth.AddLine(TopLeft, TopRight);
                    pth.AddLine(TopRight, Bottom);

                    // Determine the arrow and button's color.
                    arrowBrush = new SolidBrush(Color.Black);

                    if (this.DroppedDown)
                    {
                        arrowBrush = new SolidBrush(Color.Red);
                        ButtonBrush = new SolidBrush(Color.PaleGreen);
                    }
                    // Draw the arrow
                    g.FillRectangle(ButtonBrush, rect);
                    g.FillPath(arrowBrush, pth);

                    pen.Dispose();
                    pth.Dispose();

                }
                finally
                {
                    // Cleanup
                    g.Dispose();
                    arrowBrush.Dispose();
                    backgroundBrush.Dispose();
                }
                break;
               
           default:
              {
                break;
              }
        }
    }

    protected override void OnDrawItem(System.Windows.Forms.DrawItemEventArgs e)
    {
        // Draw Dropdown with Multicolumns
        Cursor = Cursors.Arrow;
        DataRowView row = (DataRowView)base.Items[e.Index];

        int newpos = e.Bounds.X;
        int endpos = e.Bounds.X;
        int intColumnIndex = 0;

        // Draw the current item text based on the current Font and the custom brush settings
        foreach (string str in columnWidthsArray)
        {
            // paint each column, "intColumnIndex" is local integer
            string strColWidth = columnWidthsArray[intColumnIndex];
            int ColLength = System.Convert.ToInt32(strColWidth);
            // Adjust ColLength
            ColLength = System.Convert.ToInt32(ColLength * intScreenMagnification / 100); // ******
            endpos += ColLength;

            string strColumnText = row[intColumnIndex].ToString();

            if (IsDate(strColumnText))  //Format Date as 'dd-MM-yy' (not avail as 'ToString("Format")'
            {
                strColumnText = strColumnText.Replace("/", "-");
                string strSaveColumn = strColumnText;
                strColumnText = strSaveColumn.Substring(0, 6) + strSaveColumn.Substring(8, 2);
                ColLength = 40;
            }

            // Paint Text
            if (ColLength > 0)
            {
                RectangleF r = new RectangleF(newpos + 1, e.Bounds.Y, endpos - 1, e.Bounds.Height);
                // Colours of normal row and text

                //   Colours of normal row and text
                SolidBrush textBrush = new SolidBrush(Color.Black);
                SolidBrush backbrush = new SolidBrush(Color.White);
                StringFormat strFormat = new StringFormat();
                try 
                {
                    // Colours of selected row and text
                    if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
                    {
                        textBrush.Color = textselectedcolor; // Red
                        backbrush.Color = bgSelectedColor; // Pale Green
                    }
                    e.Graphics.FillRectangle(backbrush, r);

                    strFormat.Trimming = StringTrimming.Character;
                    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                    e.Graphics.DrawString(strColumnText, e.Font, textBrush, r, strFormat);
                    e.Graphics.SmoothingMode = SmoothingMode.None;
                }
                finally
                { 
                    backbrush.Dispose();
                    strFormat.Dispose();
                    textBrush.Dispose();
                }

                //Separate columns with white border
                if (intColumnIndex > 0 && intColumnIndex <= (columnWidthsArray.Length))
                {
                    e.Graphics.DrawLine(new Pen(Color.White), endpos, e.Bounds.Y, endpos, ItemHeight * MaxDropDownItems);
                }
                newpos = endpos;
                intColumnIndex++;
            } // end if
        }// end for
    } //end sub

private bool IsDate(string strColumnText)
{
    DateTime dateValue;

    if (DateTime.TryParse(strColumnText, out dateValue))
    {
        return true;
    }
    else
    {
        return false;
    }
} // end sub

    protected override void OnMouseWheel(MouseEventArgs e)
    {
        // Overrides Sub of same name in parent class
        HandledMouseEventArgs MWheel = (HandledMouseEventArgs)e;
        // HandledMouseEventArgs prevents event being sent to parent container
        if (!this.DroppedDown)
        {
            MWheel.Handled = true;
        }
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);
        if (!this.DroppedDown & e.KeyCode == Keys.Down)
            this.DroppedDown = true;
        else if (e.KeyCode == Keys.Escape)
        {
            this.SelectedIndex = -1;
            this.Text = "";
        }
    }
}

答案 6 :(得分:0)

您不能拥有多列组合框。

使用DataGridView取代

会不会更好

答案 7 :(得分:0)

快速解决方案
就我记得

而言,数据表应该是主题类
  1. 为您的数据表创建第二个文件 MyDataTable.custom.cs
  2. 在名为的部分数据表类中添加字符串属性 “DisplayProperty”
  3. 在该属性中返回string.format(“{0} {1} {2}”, Aundragsnummer,Kunde, Beschreibung);
  4. 将您的Datamember绑定到DisplayProperty

答案 8 :(得分:0)

MultiColumn ComboBox Control组合了要编辑的文本框控件和下拉列表中的网格视图以显示数据。

答案 9 :(得分:0)

简单快捷! 看这个...

combobox.Datasource = 
entities.tableName.Select(a => a.Coulmn1 + " " + a.Coulmn2).ToList();

答案 10 :(得分:0)

我为多列组合框提供的完整C#解决方案在使用它的应用程序中进行调试时引起了问题。 问题出在“ DateTime dt = DateTime.Parse(strColumnText);”行上。在方法中 “日期” 这是使用DateTimeTryparse的方法的新版本”: 我已替换了原来的错误版本。 (NB对于所有缺点,都可以使用!) 干杯, 布鲁斯·考德威尔

     private bool IsDate(string strColumnText)
    {
        DateTime dateValue;

        if (DateTime.TryParse(strColumnText, out dateValue))
        {
            return true;
        }
        else
        {
            return false;
        }
    } // end sub