|
Can Anyone post me the link or code for multi column combo box using c# (Win Forms).
Thanks in Advance
| | VRReddy0560 Wednesday, October 07, 2009 8:08 PM | This is by no means a polished solution but it might give you a push in the right direction.
using System.Drawing;
using System.Windows.Forms;
namespace MSDN.Forums.Example
{
public interface IHaveColumnsItem
{
string Column1Value { get; }
string Column2Value { get; }
}
public class MultiColumnComboBox : ComboBox
{
private bool _hasMultiColumns = false;
private int _maxItemWidth = 0;
private const int PADDING = 5;
public MultiColumnComboBox()
: base()
{
DrawMode = DrawMode.OwnerDrawVariable;
}
protected override void OnDrawItem( DrawItemEventArgs e )
{
base.OnDrawItem( e );
object obj = this.Items[ e.Index ];
string column1Text = GetItemTextInternal( obj );
e.Graphics.FillRectangle( new SolidBrush( e.BackColor ), e.Bounds );
e.Graphics.DrawString( column1Text, this.Font, new SolidBrush( this.ForeColor ), e.Bounds.Left, e.Bounds.Top );
if( _hasMultiColumns )
e.Graphics.DrawLine( SystemPens.ControlText, _maxItemWidth + PADDING, e.Bounds.Top, _maxItemWidth + PADDING, e.Bounds.Height );
if( typeof( IHaveColumnsItem ).IsAssignableFrom( obj.GetType() ) )
{
string column2Text = ( ( IHaveColumnsItem )obj ).Column2Value;
e.Graphics.DrawString( column2Text, this.Font, new SolidBrush( this.ForeColor ), _maxItemWidth + ( PADDING * 2 ), e.Bounds.Top );
}
}
protected override void OnMeasureItem( MeasureItemEventArgs e )
{
// Reset if we're measuring from the begining.
if( e.Index == 0 ) _maxItemWidth = 0;
string itemText = GetItemTextInternal( this.Items[ e.Index ] );
Size size = e.Graphics.MeasureString( itemText, this.Font ).ToSize();
if( _maxItemWidth < size.Width )
_maxItemWidth = size.Width;
base.OnMeasureItem( e );
}
private string GetItemTextInternal( object obj )
{
if( typeof( IHaveColumnsItem ).IsAssignableFrom( obj.GetType() ) )
{
_hasMultiColumns = true;
return ( ( IHaveColumnsItem )obj ).Column1Value;
}
else return GetItemText( obj ); // The default list control method
}
}
}
Hope it helps you some.
"There's a way to do it better - find it." - Thomas Edison - Marked As Answer byAland LiMSFT, Moderator2 hours 49 minutes ago
-
| | Derik Palacino Thursday, October 08, 2009 1:20 AM | It's used like this...
public Form1()
{
InitializeComponent();
multiColumnComboBox1.Items.AddRange( new object[] {
"Item",
"Longer Item",
"An Event Longer Item",
"The Longest Item So Far"} );
multiColumnComboBox1.Items.Add( new MultiColumnItem()
{
Column1Value = "Value 1",
Column2Value = "Value 2"
} );
}
"There's a way to do it better - find it." - Thomas Edison - Marked As Answer byAland LiMSFT, Moderator2 hours 49 minutes ago
-
| | Derik Palacino Thursday, October 08, 2009 1:22 AM | With an item object like this...
public class MultiColumnItem : IHaveColumnsItem
{
public string Column1Value { get; set; }
public string Column2Value { get; set; }
}
Sorry for the multiple posts.
"There's a way to do it better - find it." - Thomas Edison - Marked As Answer byAland LiMSFT, Moderator2 hours 49 minutes ago
-
| | Derik Palacino Thursday, October 08, 2009 1:22 AM | Use the DrawItem event to draw the columns: public partial class Form1 : Form { public Form1() { InitializeComponent(); comboBox1.Items.Add("1,one"); comboBox1.Items.Add("2,two"); comboBox1.Items.Add("3,three"); comboBox1.DrawMode = DrawMode.OwnerDrawFixed; comboBox1.DrawItem += new DrawItemEventHandler(comboBox1_DrawItem); } private const int wcol1 = 20; void comboBox1_DrawItem(object sender, DrawItemEventArgs e) { string txt = comboBox1.Items[e.Index].ToString(); string[] words = txt.Split(','); e.DrawBackground(); Color fore = Color.FromKnownColor(KnownColor.WindowText); if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) fore = Color.FromKnownColor(KnownColor.HighlightText); TextFormatFlags fmt = TextFormatFlags.Left; Rectangle wordRc1 = new Rectangle(e.Bounds.Left, e.Bounds.Top, wcol1, e.Bounds.Height); TextRenderer.DrawText(e.Graphics, words[0], comboBox1.Font, wordRc1, fore, fmt); Rectangle wordRc2 = new Rectangle(e.Bounds.Left+wcol1, e.Bounds.Top, e.Bounds.Width-wcol1, e.Bounds.Height); TextRenderer.DrawText(e.Graphics, words[1], comboBox1.Font, wordRc2, fore, fmt); e.DrawFocusRectangle(); } }
Hans Passant.- Marked As Answer byAland LiMSFT, Moderator2 hours 49 minutes ago
-
| | nobugz Thursday, October 08, 2009 1:31 AM | This is by no means a polished solution but it might give you a push in the right direction.
using System.Drawing;
using System.Windows.Forms;
namespace MSDN.Forums.Example
{
public interface IHaveColumnsItem
{
string Column1Value { get; }
string Column2Value { get; }
}
public class MultiColumnComboBox : ComboBox
{
private bool _hasMultiColumns = false;
private int _maxItemWidth = 0;
private const int PADDING = 5;
public MultiColumnComboBox()
: base()
{
DrawMode = DrawMode.OwnerDrawVariable;
}
protected override void OnDrawItem( DrawItemEventArgs e )
{
base.OnDrawItem( e );
object obj = this.Items[ e.Index ];
string column1Text = GetItemTextInternal( obj );
e.Graphics.FillRectangle( new SolidBrush( e.BackColor ), e.Bounds );
e.Graphics.DrawString( column1Text, this.Font, new SolidBrush( this.ForeColor ), e.Bounds.Left, e.Bounds.Top );
if( _hasMultiColumns )
e.Graphics.DrawLine( SystemPens.ControlText, _maxItemWidth + PADDING, e.Bounds.Top, _maxItemWidth + PADDING, e.Bounds.Height );
if( typeof( IHaveColumnsItem ).IsAssignableFrom( obj.GetType() ) )
{
string column2Text = ( ( IHaveColumnsItem )obj ).Column2Value;
e.Graphics.DrawString( column2Text, this.Font, new SolidBrush( this.ForeColor ), _maxItemWidth + ( PADDING * 2 ), e.Bounds.Top );
}
}
protected override void OnMeasureItem( MeasureItemEventArgs e )
{
// Reset if we're measuring from the begining.
if( e.Index == 0 ) _maxItemWidth = 0;
string itemText = GetItemTextInternal( this.Items[ e.Index ] );
Size size = e.Graphics.MeasureString( itemText, this.Font ).ToSize();
if( _maxItemWidth < size.Width )
_maxItemWidth = size.Width;
base.OnMeasureItem( e );
}
private string GetItemTextInternal( object obj )
{
if( typeof( IHaveColumnsItem ).IsAssignableFrom( obj.GetType() ) )
{
_hasMultiColumns = true;
return ( ( IHaveColumnsItem )obj ).Column1Value;
}
else return GetItemText( obj ); // The default list control method
}
}
}
Hope it helps you some.
"There's a way to do it better - find it." - Thomas Edison - Marked As Answer byAland LiMSFT, Moderator2 hours 49 minutes ago
-
| | Derik Palacino Thursday, October 08, 2009 1:20 AM | It's used like this...
public Form1()
{
InitializeComponent();
multiColumnComboBox1.Items.AddRange( new object[] {
"Item",
"Longer Item",
"An Event Longer Item",
"The Longest Item So Far"} );
multiColumnComboBox1.Items.Add( new MultiColumnItem()
{
Column1Value = "Value 1",
Column2Value = "Value 2"
} );
}
"There's a way to do it better - find it." - Thomas Edison - Marked As Answer byAland LiMSFT, Moderator2 hours 49 minutes ago
-
| | Derik Palacino Thursday, October 08, 2009 1:22 AM | With an item object like this...
public class MultiColumnItem : IHaveColumnsItem
{
public string Column1Value { get; set; }
public string Column2Value { get; set; }
}
Sorry for the multiple posts.
"There's a way to do it better - find it." - Thomas Edison - Marked As Answer byAland LiMSFT, Moderator2 hours 49 minutes ago
-
| | Derik Palacino Thursday, October 08, 2009 1:22 AM | Use the DrawItem event to draw the columns: public partial class Form1 : Form { public Form1() { InitializeComponent(); comboBox1.Items.Add("1,one"); comboBox1.Items.Add("2,two"); comboBox1.Items.Add("3,three"); comboBox1.DrawMode = DrawMode.OwnerDrawFixed; comboBox1.DrawItem += new DrawItemEventHandler(comboBox1_DrawItem); } private const int wcol1 = 20; void comboBox1_DrawItem(object sender, DrawItemEventArgs e) { string txt = comboBox1.Items[e.Index].ToString(); string[] words = txt.Split(','); e.DrawBackground(); Color fore = Color.FromKnownColor(KnownColor.WindowText); if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) fore = Color.FromKnownColor(KnownColor.HighlightText); TextFormatFlags fmt = TextFormatFlags.Left; Rectangle wordRc1 = new Rectangle(e.Bounds.Left, e.Bounds.Top, wcol1, e.Bounds.Height); TextRenderer.DrawText(e.Graphics, words[0], comboBox1.Font, wordRc1, fore, fmt); Rectangle wordRc2 = new Rectangle(e.Bounds.Left+wcol1, e.Bounds.Top, e.Bounds.Width-wcol1, e.Bounds.Height); TextRenderer.DrawText(e.Graphics, words[1], comboBox1.Font, wordRc2, fore, fmt); e.DrawFocusRectangle(); } }
Hans Passant.- Marked As Answer byAland LiMSFT, Moderator2 hours 49 minutes ago
-
| | nobugz Thursday, October 08, 2009 1:31 AM | Hi VRReddy0560, You can take a look at this sample: http://www.codeproject.com/KB/combobox/multicolumncombo.aspxRegards, Aland Li
Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. | | Aland Li 2 hours 49 minutes ago |
|