C# 如何重写winforms combobox项集合以实现特定接口

C# 如何重写winforms combobox项集合以实现特定接口,c#,winforms,combobox,C#,Winforms,Combobox,combobox控件接受对象作为其集合成员,是否有方法约束该对象以实现特定接口 所以不是 public int Add(object item) 我想重写add方法,如下所示 public int Add<T>(T item) : where T : ICustomInterface public int Add(T项):其中T:ICustomInterface 我正在编写自己的自定义控件,该控件继承自combobox,但我不确定如何最好地让自定义combobox只处理实现特定

combobox控件接受对象作为其集合成员,是否有方法约束该对象以实现特定接口

所以不是

public int Add(object item)
我想重写add方法,如下所示

public int Add<T>(T item) : where T : ICustomInterface
public int Add(T项):其中T:ICustomInterface
我正在编写自己的自定义控件,该控件继承自combobox,但我不确定如何最好地让自定义combobox只处理实现特定接口的项


谢谢你

你可以使用以下技巧来做到这一点。我发现
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);
        }
    }
}