我目前在Windows窗体应用程序中有一个ComboBox。为了指定ComboBox将包含哪些值,我将ComboBox的DataSource属性设置为某个数组,以便ComboBox包含该数组的值。我还可以使用Items.Add()
向ComboBox添加新值。但是,我想确保ComboBox可以填充某些特定类型的对象。所以,如果我有一个名为X的类,那么我想使它只有一个X类型的数组可以用作ComboBox的数据源。现在,ComboBox接受System.Object
类型的对象。我怎样才能实现它? ComboBox的属性是否需要设置为等于我的数据类型名称?或者是否有一个事件会检查添加到我的ComboBox的对象是否属于所需类型,如果没有则抛出异常?
我正在考虑创建一个新类作为ComboBox的子类型,并覆盖Add
属性的Items
方法,以便Add检查其参数是否属于所需类型(不确定是否和我怎么能这样做)。即使我这样做,还有其他方法可以将新值添加到ComboBox(AddRange
,CopyTo
等),所以我认为应该有一个更优雅的解决方案来解决这个问题。
答案 0 :(得分:2)
如果您想控制ComboBox
可以包含的项目类型,您可以尝试创建一个新的类派生形式ComboBox
,但是您会遇到它仍然具有的问题ComboBox.ObjectCollection Items
属性仍然可以接受任何类型!而且(遗憾的是,您的覆盖想法)Add
方法不是虚拟的。
我能想到的唯一可行的解决方案是以某种方式抽象ComboBox
。如果这不是共享代码,我建议您只创建一个用于向ComboBox
添加项目的方法。类似的东西:
// NOTE: All items that are added to comboBox1 need to be of type `SomeType`.
private void AddItemToComboBox(SomeType item)
{
comboBox1.Items.Add(item);
}
任何向SomeType
添加非ComboBox
对象的尝试都会遇到编译器错误。不幸的是,没有简单的方法可以阻止某人直接向SomeType
添加非ComboBox.Items
项。
同样,如果这不是共享代码,那么它应该不是问题。
答案 1 :(得分:1)
您可以通过您的<隐藏Items
财产
自定义类型的Items
属性,其作为参数原始ItemsCollection
测试的示例类
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;
}
}
下一课我尝试用自己的类型包装ComboBox的项目集合。 添加项目必须是具体类型 在这里,您可以添加所需的其他方法/属性(删除)
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; } }
}
这里自定义组合框类派生自ComboBox 补充:通用类型
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; }
}
}
表单中使用的下一个代码
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);
}
答案 2 :(得分:0)
您可以覆盖usercontrol,向其添加一个组合框,然后只显示您希望使用的元素,而不是覆盖ComboBox(它不会像itsme86's answer中所述那样工作)。类似于
的东西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>(); }
}
}
但请注意,某些自动化软件依赖于访问基础控件,但这可能会导致一些问题。
此方法永远不会更改组合框的Items
,因此它们仍将存储为objects
但是当您访问它们时,您将它们转换为正确的类型,并且只允许它们添加类型。您可以通过
var myCB = new MyComboBox<ItemClass>();