Как скрыть свойство Items в пользовательском ComboBox

1

Я создаю настраиваемый элемент управления, который наследуется от ComboBox. Мне нужно выполнить пользовательское действие, когда элемент добавляется в ComboBox. Неважно, если это С# или Vb.NET, но я не знаю, как это сделать.

Похоже, что не стоит пытаться изменить все, чтобы обнаружить это, как видно здесь:
Событие для обнаружения элемента, добавленного в ComboBox

Возможно, возможно создать мой пользовательский .Add(); метод, но тогда мне нужно скрыть свойство Items чтобы элемент управления не позволял использовать два разных метода добавления и только один рабочий.

Я пытался использовать вещи в этом потоке, но мне не удалось заставить его работать. Например, я попытался поместить переопределенное свойство private, но ничего не изменил, как показано в этом примере в Vb.NET:

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

Это можно сделать?

  • 0
    Как бы они добавили вещи, если вы скрываете Items ?
  • 0
    @Plutonix с моим собственным методом AddItem
Показать ещё 6 комментариев
Теги:
winforms
combobox

2 ответа

2

Да и нет.

Да, вы можете скрыть оригинальную коллекцию предметов и заменить ее чем - то другим.

Однако ваши новые "пользовательские" элементы не смогут работать; это всегда нулевое - по крайней мере, то, что я нашел. Может быть, кто-то может вскочить с подробностями о том, почему...?

Вот почему я заменяю его чем-то бесполезным - голым объектом.

Что вы можете сделать, так это: вы можете открыть оригинальные элементы в классе "человек в середине" и использовать его в своем классе ComboBox. Вы могли бы, например, назвать открытый класс 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; } } 

    }

}

Это пример использования ComboBox:

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

то (3) будет компилироваться просто отлично. Однако во время выполнения он генерирует ошибку ссылки на нулевой объект.

Является ли это запоздалым эффектом недостающего атрибута Overridable? @Jon Skeet на помощь! ;-)

  • 0
    очень интересно Частично это работает только в C #; преобразован в VB (я думаю, более четко в VB) Intellisence показывает и использует .items_ - это потому, что VB не чувствителен к регистру, поэтому items не могут заменить Items . Я сделал несколько настроек, пытаясь сделать его более функциональным; не стесняйтесь добавлять / изменять / игнорировать по желанию: pastebin.com/fSF6ZjTf
1

MyComboBox действует как обычное combobox (путем перезаписи свойства Item) с расширенными событиями (ItemAdded, ItemRemoved)

Пример использования:

    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

Конечный класс

Код С#:

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

    }

}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню