c# - 如何覆盖 winforms 组合框项目集合以实现特定接口(interface)

标签 c# winforms combobox

组合框控件接受一个对象作为其集合成员,有没有办法约束该对象实现某个接口(interface)?

所以而不是

public int Add(object item)

我想将 add 方法重写为以下几行

public int Add<T>(T item) : where T : ICustomInterface

我正在编写自己的继承自组合框的自定义控件,但我不太确定如何最好地让自定义组合框仅处理实现特定接口(interface)的项目。

谢谢

最佳答案

您可以使用以下技巧来做到这一点。我发现 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 包含一个内部列表。我们所要做的就是覆盖它。不幸的是,我们必须使用反射,因为这个字段是私有(private)的。这是检查它的代码。

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);
        }
    }
}

关于c# - 如何覆盖 winforms 组合框项目集合以实现特定接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45884121/

相关文章:

c# - OpenXml Word 脚注

winforms - Winforms Designer 如何实例化我的表单?

c++ - 在 C++ 中刷新组合框?

mysql - 组合框不使用绑定(bind)导航器记录选择器显示下一条记录

c# - 无法连接到 FTP : (553) File name not allowed

c# - 从 C# 导出 xls 文件 - 不保存特殊字母

c# - 找不到 C# Winforms 中的内存泄漏

C# Texbox 的 'MaxLength' 属性 - 故障 (Winform)

mysql - 获取 ComboBox 中非显示成员项的值

c# - 如果打开自定义错误,是否不会触发 global.asax Application_Error 事件?