如何在自定义组合框中隐藏Items属性

本文关键字:隐藏 Items 属性 组合 自定义 | 更新日期: 2023-09-27 18:13:08

我正在创建一个继承自ComboBox的自定义控件。当Item被添加到ComboBox中时,我需要执行一个自定义操作。不管用c#还是Vb。. NET,但是我不知道怎么做。

看起来不值得修改所有内容来检测它,如下所示:
事件来检测添加到ComboBox中的项

所以也许是有可能创建我的自定义.Add();方法,但然后我需要隐藏Items属性,所以控件不允许添加两种不同的方法,只有一个工作。

我试着在这个线程中使用东西,但我没有设法使它工作。例如,我试着把重载属性private,但没有改变任何东西,如在Vb中看到的这个例子。净:

Private Overloads ReadOnly Property Items() As ObjectCollection
'...

可以做到吗?

如何在自定义组合框中隐藏Items属性

是和不是。

是的,您可以隐藏原始Items集合,并将其替换为其他

然而,你的新"自定义"项目将无法工作;它总是空的——至少我是这么发现的。也许有人能告诉我为什么…?

这就是为什么我用一些相当无用的东西来代替它——一个裸露的物体。

可以做的是:您可以在man-in-the-middle类中公开原始Items,并在您的自定义ComboBox类中使用它。例如,你可以将暴露的类命名为Items_,并创建一个类来替换最终继承层中的Items。这个类需要实现你希望自定义类的消费者拥有的所有方法和属性。

我已经命名自定义项目' Items ',并实现了一个方法和一个属性。(对于不区分大小写的VB, Itemz可能会更好;-)

这是最小的人在中间:

[ToolboxItem(false)]
public class mimComboBox : ComboBox
{
    public ObjectCollection items_;
    public mimComboBox()
    {
        items_ = Items;
    }
}

这是一个自定义的ComboBox:

public class myComboBox : mimComboBox
{
    public myComboBox()
    {
        Items = new object();               // (1)
        items = new myItems(this);
    }
    new public object Items { get; set; }  // this hides the real Items  (2)
    public myItems items { get; set; }     // this is the custom property
    public class myItems // the custom Items class with all necessary methods etc..
    {
        public myItems( myComboBox parent )
        {
            parentCB = parent;  // reference to the outer class
        }
        private mimComboBox parentCB;  // the man-in-the-middle
        // all your methods..
        new public int Add(object o)  // one example of a custom method
        {
            // add your item-added event here
            return parentCB.items_.Add(o);
        }
        // one of many many properties  to provide..
        public int Count { get { return parentCB.items_.Count; } } 
    }
}

这是一个如何使用组合框的例子:

private void button1_Click(object sender, EventArgs e)
{
    myComboBox1.items.Add("uiuiuiiui");
    // myComboBox1.Items.Add("sadsds");  // <== this doesn't compile! (3)
    button1.Text = myComboBox1.items.Count.ToString();
}

这听起来像是相当多的工作!!

也许中产阶级是不必要的…?我想了解一下……!)

编辑:我已经根据Plutonix评论中的链接更改了一些细节。

指出:

  • 如上所述,最初的问题最好通过收听ComboBox系统消息

  • 来解决。
  • 我仍然想知道为什么会发生这种情况:

当我替换(1)&(2)

Items = new myItems(this);
new public myItems Items { get; set; } 

then(3)可以很好地编译。但是在运行时抛出空对象引用错误。

这是缺失的Overridable属性的迟来的影响吗?@乔恩·斯基特来救援!: -)

MyComboBox使用扩展事件(ItemAdded, ItemRemoved)作为普通的combobox(通过覆盖Item属性)

示例用法:

    MyComboBox1.Items.Add("0")
    MyComboBox1.Items.AddRange(New String() {"1", "2", "3", "55"})
    MyComboBox1.Items.Remove("55")
    MyComboBox1.Items.RemoveAt(0)
    Debug.WriteLine(MyComboBox1.Items.IndexOf("2")) '2
    Debug.WriteLine(MyComboBox1.Items.IndexOf("55")) '-1
    MyComboBox1.Items.Clear()

VB。NET代码:

Public Class MyComboBox
Inherits ComboBox
Public Event ItemAdded As EventHandler
'Public Event ItemsAdded As EventHandler
Public Event ItemRemoved As EventHandler
'Public Event ItemInserted(sender As Object, insertedIndex As Integer, e As EventArgs)
Private ItemContainer_ As ItemContainer
Sub New()
    ItemContainer_ = New ItemContainer(Me)
    AddHandler ItemContainer_.ItemAdded, AddressOf ItemContainer_ItemAdded
    'AddHandler ItemContainer_.ItemsAdded, AddressOf ItemContainer_ItemsAdded
    AddHandler ItemContainer_.ItemRemoved, AddressOf ItemContainer_ItemRemoved
    'AddHandler ItemContainer_.ItemInserted, AddressOf ItemContainer_ItemInserted
End Sub
Private Sub ItemContainer_ItemAdded(sender As Object, e As EventArgs)
    RaiseEvent ItemAdded(Me, e)
End Sub
'Private Sub ItemContainer_ItemsAdded(sender As Object, e As EventArgs)
'    RaiseEvent ItemsAdded(Me, e)
'End Sub
Private Sub ItemContainer_ItemRemoved(sender As Object, e As EventArgs)
    RaiseEvent ItemRemoved(Me, e)
End Sub
'Private Sub ItemContainer_ItemInserted(sender As Object, insertedIndex As Integer, e As EventArgs)
'    RaiseEvent ItemInserted(Me, insertedIndex, e)
'End Sub
Public Shadows ReadOnly Property Items As ItemContainer
    Get
        Return ItemContainer_
    End Get
End Property
Public Shadows ReadOnly Property Items(index As Integer) As Object
    Get
        Return ItemContainer_.Item(index)
    End Get
End Property

Public Class ItemContainer
    Inherits System.Windows.Forms.ComboBox.ObjectCollection
    Public Event ItemAdded As EventHandler
    'Public Event ItemsAdded As EventHandler
    Public Event ItemRemoved As EventHandler
    'Public Event ItemInserted(sender As Object, insertedIndex As Integer, e As EventArgs)

    Private owner_ As ComboBox
    Sub New(owner As ComboBox)
        MyBase.New(owner)
        owner_ = owner
    End Sub

    Public Overloads Sub Add(item As Object)
        owner_.Items.Add(item)
        RaiseEvent ItemAdded(Me, New EventArgs)
    End Sub
    Public Overloads Sub AddRange(item() As Object)
        owner_.Items.AddRange(item)
        'RaiseEvent ItemsAdded(Me, New EventArgs)
        RaiseEvent ItemAdded(Me, New EventArgs)
    End Sub
    Public Overloads Sub Insert(index As Integer, item As Object)
        owner_.Items.Insert(index, item)
        'RaiseEvent ItemInserted(Me, index, New EventArgs)
        RaiseEvent ItemAdded(Me, New EventArgs)
    End Sub

    Public Overloads Sub Remove(item As Object)
        owner_.Items.Remove(item)
        RaiseEvent ItemRemoved(Me, New EventArgs)
    End Sub
    Public Overloads Sub RemoveAt(index As Integer)
        owner_.Items.RemoveAt(index)
        RaiseEvent ItemRemoved(Me, New EventArgs)
    End Sub
    Public Overloads Sub Clear()
        owner_.Items.Clear()
        RaiseEvent ItemRemoved(Me, New EventArgs)
    End Sub

    Public Overloads Function IndexOf(value As Object) As Integer
        Return owner_.Items.IndexOf(value)
    End Function
    Public Overloads Function Contains(value As Object) As Boolean
        Return owner_.Items.Contains(value)
    End Function
    Public Overloads Function GetHashCode() As Integer
        Return owner_.Items.GetHashCode
    End Function
    Public Overloads Function ToString() As String
        Return owner_.Items.ToString
    End Function
    Public Overloads Function GetEnumerator() As System.Collections.IEnumerator
        Return owner_.Items.GetEnumerator
    End Function
    Public Overloads Function Equals(obj As Object) As Boolean
        Return owner_.Items.Equals(obj)
    End Function
    Public Overloads Function Equals(objA As Object, objB As Object) As Boolean
        Return Object.Equals(objA, objB)
    End Function
    Public Overloads Sub CopyTo(Destination() As Object, arrayIndex As Integer)
        owner_.Items.CopyTo(Destination, arrayIndex)
    End Sub

    Public Overloads ReadOnly Property Count As Integer
        Get
            Return owner_.Items.Count
        End Get
    End Property
    Public Overloads ReadOnly Property IsReadOnly As Boolean
        Get
            Return owner_.Items.IsReadOnly
        End Get
    End Property
    Public Overloads ReadOnly Property Item(index As Integer) As Object
        Get
            Return owner_.Items.Item(index)
        End Get
    End Property

End Class

结束课c#代码:

    using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class MyComboBox : System.Windows.Forms.ComboBox
{
    public event EventHandler ItemAdded;
    //public event EventHandler ItemsAdded;
    public event EventHandler ItemRemoved;
    public event ItemInsertedEventHandler ItemInserted;
    public delegate void ItemInsertedEventHandler(object sender, int insertedIndex, EventArgs e);

    private ItemContainer ItemContainer_;
    public MyComboBox()
    {
        ItemContainer_ = new ItemContainer(this);
        ItemContainer_.ItemAdded += ItemContainer_ItemAdded;
        //ItemContainer_.ItemsAdded += ItemContainer_ItemsAdded;
        ItemContainer_.ItemRemoved += ItemContainer_ItemRemoved;
        ItemContainer_.ItemInserted += ItemContainer_ItemInserted;
    }
    private void ItemContainer_ItemAdded(object sender, EventArgs e)
    {
        if (ItemAdded != null)
        {
            ItemAdded(this, e);
        }
    }
    /*private void ItemContainer_ItemsAdded(object sender, EventArgs e)
    {
        if (ItemsAdded != null)
        {
            ItemsAdded(this, e);
        }
    }*/
    private void ItemContainer_ItemRemoved(object sender, EventArgs e)
    {
        if (ItemRemoved != null)
        {
            ItemRemoved(this, e);
        }
    }
    private void ItemContainer_ItemInserted(object sender, int insertedIndex, EventArgs e)
    {
        if (ItemInserted != null)
        {
            ItemInserted(this, insertedIndex, e);
        }
    }
    public new ItemContainer Items
    {
        get { return ItemContainer_; }
    }

    public class ItemContainer : System.Windows.Forms.ComboBox.ObjectCollection
    {
        public event EventHandler ItemAdded;
        //public event EventHandler ItemsAdded;
        public event EventHandler ItemRemoved;
        public event ItemInsertedEventHandler ItemInserted;
        public delegate void ItemInsertedEventHandler(object sender, int insertedIndex, EventArgs e);

        private System.Windows.Forms.ComboBox owner_;
        public ItemContainer(System.Windows.Forms.ComboBox owner)
            : base(owner)
        {
            owner_ = owner;
        }

        public new void Add(object item)
        {
            owner_.Items.Add(item);
            if (ItemAdded != null)
            {
                ItemAdded(this, new EventArgs());
            }
        }
        public new void AddRange(object[] item)
        {
            owner_.Items.AddRange(item);
            /*if (ItemsAdded != null)
            {
                ItemsAdded(this, new EventArgs());
            }*/
            if (ItemAdded != null)
            {
                ItemAdded(this, new EventArgs());
            }
        }
        public new void Insert(int index, object item)
        {
            owner_.Items.Insert(index, item);
            if (ItemInserted != null)
            {
                ItemInserted(this, index, new EventArgs());
            }
        }

        public new void Remove(object item)
        {
            owner_.Items.Remove(item);
            if (ItemRemoved != null)
            {
                ItemRemoved(this, new EventArgs());
            }
        }
        public new void RemoveAt(int index)
        {
            owner_.Items.RemoveAt(index);
            if (ItemRemoved != null)
            {
                ItemRemoved(this, new EventArgs());
            }
        }
        public new void Clear()
        {
            owner_.Items.Clear();
            if (ItemRemoved != null)
            {
                ItemRemoved(this, new EventArgs());
            }
        }

        public new int IndexOf(object value)
        {
            return owner_.Items.IndexOf(value);
        }
        public new bool Contains(object value)
        {
            return owner_.Items.Contains(value);
        }
        public new int GetHashCode()
        {
            return owner_.Items.GetHashCode();
        }
        public new string ToString()
        {
            return owner_.Items.ToString();
        }
        public new System.Collections.IEnumerator GetEnumerator()
        {
            return owner_.Items.GetEnumerator();
        }
        public new bool Equals(object obj)
        {
            return owner_.Items.Equals(obj);
        }
        public new bool Equals(object objA, object objB)
        {
            return object.Equals(objA, objB);
        }
        public new void CopyTo(object[] Destination, int arrayIndex)
        {
            owner_.Items.CopyTo(Destination, arrayIndex);
        }

        public new int Count
        {
            get { return owner_.Items.Count; }
        }
        public new object this[int index]
        {
            get { return owner_.Items[index]; }
        }
        public new bool IsReadOnly
        {
            get { return owner_.Items.IsReadOnly; }
        }
    }
}