您可以使用以下技巧來做到這一點。我發現RefreshItems()
和構造函數是實現這一點的關鍵地方。
using System;
using System.Reflection;
namespace WindowsFormsApplication2
{
interface ICustomInterface
{
}
public class ArrayList : System.Collections.ArrayList
{
public override int Add(object value)
{
if (!(value is ICustomInterface))
{
throw new ArgumentException("Only 'ICustomInterface' can be added.", "value");
}
return base.Add(value);
}
}
public sealed class MyComboBox : System.Windows.Forms.ComboBox
{
public MyComboBox()
{
FieldInfo fieldInfo = typeof(System.Windows.Forms.ComboBox.ObjectCollection).GetField("innerList", BindingFlags.NonPublic | BindingFlags.Instance);
fieldInfo.SetValue(this.Items, new ArrayList());
}
protected override void RefreshItems()
{
base.RefreshItems();
FieldInfo fieldInfo = typeof(System.Windows.Forms.ComboBox.ObjectCollection).GetField("innerList", BindingFlags.NonPublic | BindingFlags.Instance);
fieldInfo.SetValue(this.Items, new ArrayList());
}
}
}
也就是說,ComboBox.ObjectCollection包含一個內部列表。我們所要做的就是重寫它。不幸的是,我們必須使用反射,因爲此字段是私人的。這裏是檢查它的代碼。
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
class MyClass : ICustomInterface
{
}
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
this.myComboBox1.Items.Add(new MyClass());
this.myComboBox1.Items.Add(new MyClass());
//Uncommenting following lines of code will produce exception.
//Because class 'string' does not implement ICustomInterface.
//this.myComboBox1.Items.Add("FFFFFF");
//this.myComboBox1.Items.Add("AAAAAA");
base.OnLoad(e);
}
}
}