The following class modifies the Item collection to return a collection of Custom items. The Property Browser uses the Collection Editor rather than the StringCollection Editor. The DrawMode property has been hidden, since this property should not be changed.
by: Mick Dohertys'
VB net Sample:
Imports System.ComponentModel Imports System.Drawing.Design Imports System.ComponentModel.Design Namespace Dotnetrix_Samples Public Class ImageCombo Inherits System.Windows.Forms.ComboBox #Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call MyBase.DrawMode = DrawMode.OwnerDrawFixed End Sub 'UserControl overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If If Not (Me.Items Is Nothing) Then For Each o As Object In Me.Items If TypeOf o Is ImageComboItem Then DirectCast(o, ImageComboItem).Dispose() End If Next End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() components = New System.ComponentModel.Container End Sub #End Region Private currentIndex As Int32 = -1 <Browsable(False), EditorBrowsable(EditorBrowsableState.Never)> _ Public Shadows ReadOnly Property DrawMode() As DrawMode Get Return DrawMode.OwnerDrawFixed End Get End Property <Editor(GetType(ImageComboItemEditor), GetType(UITypeEditor)), _ DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _ Public Shadows ReadOnly Property Items() As ObjectCollection Get Return MyBase.Items End Get End Property Private Class ImageComboItemEditor Inherits CollectionEditor Public Sub New(ByVal type As Type) MyBase.New(type) End Sub Protected Overrides Function CreateCollectionItemType() As System.Type Return GetType(ImageComboItem) End Function End Class Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs) If e.Index = -1 OrElse e.Index > Me.Items.Count - 1 Then Return e.DrawBackground() Dim imageRect As Rectangle = New Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Height, e.Bounds.Height) Dim textRectF As RectangleF = RectangleF.FromLTRB(imageRect.Right + 2, e.Bounds.Top, e.Bounds.Right, e.Bounds.Bottom) If TypeOf Items(e.Index) Is ImageComboItem Then Dim Item As ImageComboItem = DirectCast(Items(e.Index), ImageComboItem) If Not (Item.Image Is Nothing) Then e.Graphics.DrawImage(Item.Image, imageRect) End If End If Dim TextBrush As New SolidBrush(Me.ForeColor) If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then TextBrush.Color = SystemColors.HighlightText End If Dim sf As New StringFormat(StringFormatFlags.NoWrap) sf.LineAlignment = StringAlignment.Center sf.Trimming = StringTrimming.EllipsisCharacter e.Graphics.DrawString(Items(e.Index).ToString, Me.Font, TextBrush, textRectF, sf) TextBrush.Dispose() End Sub Protected Overrides Sub OnSelectedIndexChanged(ByVal e As System.EventArgs) If Me.SelectedIndex <> currentIndex Then currentIndex = Me.SelectedIndex MyBase.RefreshItem(Me.SelectedIndex) Else MyBase.OnSelectedIndexChanged(e) End If End Sub End Class <DesignTimeVisible(False)> _ Public Class ImageComboItem Inherits Component Private m_object As Object Private m_Image As Image <TypeConverter(GetType(StringConverter))> _ Public Property [Item]() As Object Get Return m_object End Get Set(ByVal Value As Object) m_object = Value End Set End Property Public Property [Image]() As Image Get Return m_Image End Get Set(ByVal Value As Image) m_Image = Value End Set End Property Public Overrides Function ToString() As String If m_object Is Nothing Then Return String.Empty Else Return m_object.ToString End If End Function End Class End Namespace
CSharp Sample:
using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using System.Drawing.Design; using System.ComponentModel.Design; namespace Dotnetrix_Samples { /// <summary> /// Summary description for ImageCombo. /// </summary> public class ImageCombo : System.Windows.Forms.ComboBox { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public ImageCombo() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); // TODO: Add any initialization after the InitializeComponent call base.DrawMode = DrawMode.OwnerDrawVariable; } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } if (this.Items != null) { foreach (Object o in this.Items) { if (o is ImageComboItem) ((ImageComboItem)o).Dispose(); } } } base.Dispose( disposing ); } #region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { components = new System.ComponentModel.Container(); } #endregion private int currentIndex = -1; [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new DrawMode DrawMode { get{return DrawMode.OwnerDrawFixed;} } [Editor(typeof(ImageComboItemEditor), typeof(UITypeEditor))] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public new ObjectCollection Items { get{return base.Items;} } private class ImageComboItemEditor : CollectionEditor { public ImageComboItemEditor(Type type):base(type){} protected override Type CreateCollectionItemType() { return typeof(ImageComboItem); } } protected override void OnDrawItem(DrawItemEventArgs e) { if (e.Index == -1 || e.Index > this.Items.Count - 1) return; e.DrawBackground(); Rectangle imageRect = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Height, e.Bounds.Height); RectangleF textRectF = RectangleF.FromLTRB(imageRect.Right + 2, e.Bounds.Top, e.Bounds.Right, e.Bounds.Bottom); if (Items[e.Index] is ImageComboItem ) { ImageComboItem Item = (ImageComboItem)Items[e.Index]; if (Item.Image != null) e.Graphics.DrawImage(Item.Image, imageRect); } SolidBrush TextBrush = new SolidBrush(this.ForeColor); if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) TextBrush.Color = SystemColors.HighlightText; StringFormat sf = new StringFormat(StringFormatFlags.NoWrap); sf.LineAlignment = StringAlignment.Center; sf.Trimming = StringTrimming.EllipsisCharacter; e.Graphics.DrawString(Items[e.Index].ToString(), this.Font, TextBrush, textRectF, sf); TextBrush.Dispose(); } protected override void OnSelectedIndexChanged(EventArgs e) { if (this.SelectedIndex != this.currentIndex) { this.currentIndex = this.SelectedIndex; base.RefreshItem(this.SelectedIndex); } else { base.OnSelectedIndexChanged (e); } } } [DesignTimeVisible(false)] public class ImageComboItem : Component { private Object m_object; private Image m_Image; [TypeConverter(typeof(StringConverter))] public Object Item { get{return m_object;} set{m_object = value;} } public Image Image { get{return m_Image;} set{m_Image = value;} } public override string ToString() { if (m_object == null) return String.Empty; else return m_object.ToString(); } } }
by: Mick Dohertys'
No comments:
Post a Comment