Make ComboBox for a specific type only
I currently have a ComboBox in my Windows Forms Application. To specify what values ββthe ComboBox will contain, I set the DataSource property for the ComboBox to some array so that the ComboBox contains values ββfrom that array. I could also use Items.Add()
to add new values ββto the ComboBox. However, I want to make sure the ComboBox can be populated with objects of a specific type. So, if I have a class called X, then I want to make it so that only an array of type X can be used as a data source for the ComboBox. Now ComboBox accepts objects of the typeSystem.Object
... How can I achieve this? Is there a ComboBox property that I need to set equal to the name of my data type? Or is there an event that will check if the object added to my ComboBox is of the required type and will there be an exception if not?
I was thinking about creating a new class as a subtype of ComboBox and overriding the Add
property method Items
so that Add will check if its argument is of the correct type (not sure what or how I can do this). Even if I do, there are still other ways to add new values ββto the ComboBox ( AddRange
, CopyTo
etc.), so I think there should be a more elegant solution to this problem.
source to share
You can hide a property Items
in your site with your own Items
custom property that takes as parameter original ItemsCollection
Example class for testing
public class Order
{
public Int32 ID { get; set; }
public string Reference { get; set; }
public Order() { }
public Order(Int32 inID, string inReference)
{
this.ID = inID;
this.Reference = (inReference == null) ? string.Empty : inReference;
}
//Very important
//Because ComboBox using .ToString method for showing Items in the list
public override string ToString()
{
return this.Reference;
}
}
In the following class, I tried to wrap a collection of ComboBox items in my own type. If adding items should be of a specific type Here you can add other methods / properties that you need (Remove)
public class ComboBoxList<TCustomType>
{
private System.Windows.Forms.ComboBox.ObjectCollection _baseList;
public ComboBoxList(System.Windows.Forms.ComboBox.ObjectCollection baseItems)
{
_baseList = baseItems;
}
public TCustomType this[Int32 index]
{
get { return (TCustomType)_baseList[index]; }
set { _baseList[index] = value; }
}
public void Add(TCustomType item)
{
_baseList.Add(item);
}
public Int32 Count { get { return _baseList.Count; } }
}
Here's a custom combobox class derived from ComboBox Added: generic type
public class ComboBoxCustomType<TCustomType> : System.Windows.Forms.ComboBox
{
//Hide base.Items property by our wrapping class
public new ComboBoxList<TCustomType> Items;
public ComboBoxCustomType() : base()
{
this.Items = new ComboBoxList<TCustomType>(base.Items);
}
public new TCustomType SelectedItem
{
get { return (TCustomType)base.SelectedItem; }
}
}
The following code used in the form
private ComboBoxCustomType<Order> _cmbCustom;
//this method used in constructor of the Form
private void ComboBoxCustomType_Initialize()
{
_cmbCustom = new ComboBoxCustomType<Order>();
_cmbCustom.Location = new Point(100, 20);
_cmbCustom.Visible = true;
_cmbCustom.DropDownStyle = ComboBoxStyle.DropDownList;
_cmbCustom.Items.Add(new Order(0, " - nothing - "));
_cmbCustom.Items.Add(new Order(1, "One"));
_cmbCustom.Items.Add(new Order(2, "Three"));
_cmbCustom.Items.Add(new Order(3, "Four"));
_cmbCustom.SelectedIndex = 0;
this.Controls.Add(_cmbCustom);
}
source to share
If you want to control the type of an element that it can contain ComboBox
, you can try to create a new derived from the class ComboBox
, but you are faced with the problem that it still has a property ComboBox.ObjectCollection Items
that will take any type anyway! And (unfortunately for your overriding idea) the method is Add
not virtual.
The only practical solution I could think of was to distract somehow ComboBox
. If this is not generic code, I would recommend just creating a method that you would use to add items to ComboBox
. Something like:
// NOTE: All items that are added to comboBox1 need to be of type `SomeType`.
private void AddItemToComboBox(SomeType item)
{
comboBox1.Items.Add(item);
}
Any attempt to add an object SomeType
to ComboBox
will fail with a compiler error. Unfortunately, there is no easy way to prevent the element from being added SomeType
to ComboBox.Items
directly.
Again, if this is not generic code, this shouldn't be a problem.
source to share
Instead of overriding the ComboBox (which doesn't work as stated in itsme86 answer ), you can override the usercontrol, add a combobox to it, and then expose only the items you wish to work with. Something similar to
public partial class MyComboBox<T> : UserControl where T: class
{
public MyComboBox()
{
InitializeComponent();
}
public void Add(T item)
{
comboBox1.Items.Add(item);
}
public IEnumerable<T> Items
{
get { return comboBox1.Items.Cast<T>(); }
}
}
Note that some parts of automated software rely on access to basic controls, so this can cause some problems.
This approach never changes the Items
dropdown, so they will be kept like objects
, but when you access them, you cast them back to the type you want and only let them add that type. You can create a new combo box via
var myCB = new MyComboBox<ItemClass>();
source to share