2014-07-15 63 views
1

我正在創建一個從ComboBox繼承的自定義控件。當項目添加到組合框時,我需要執行自定義操作。不管它是C#還是Vb.NET,但我不知道如何去做。如何在自定義組合框中隱藏Items屬性

看起來不值得修改的一切,以檢測它的努力,因爲在這裏看到:
Event to detect item added to ComboBox

因此,也許可以創建我的自定義.Add();方法,但後來我需要隱藏Items屬性,以便該控件不允許兩種不同的添加方法,並且只有一種工作方式。

我嘗試使用this thread中的東西,但是我沒有設法使它工作。例如,我試圖把超載的財產private,但並沒有改變任何東西,因爲在這個例子中看到Vb.NET:

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

能不能做到?

+0

他們會如何,如果你的影子了'Items'添加的東西呢? – Plutonix

+0

@Plutonix用我自定義的'AddItem'方法 – SysDragon

+0

好吧,我該怎麼辦'對於每個s作爲字符串在yourCBO.Items'中;或者獲得'Items.Count'或者做'Items.Contains'或者.remove或者.removeat?看到問題了嗎? – Plutonix

回答

2

是和否。

是的,你可以隱藏原項目集合和東西人換掉它。

但是,您的新'自定義'項目將無法工作;它始終是空的 - 至少這是我發現的。也許有人可以跳進細節爲什麼......?

這就是爲什麼我用一些無用的東西來代替它 - 一個裸體物體。

可以做的是這樣的:你可以在中間人類暴露原始的項目,並在你的自定義組合框類中使用它。你可以例如命名公開的類Items_並創建一個類來替換最終繼承級別的Items。此類需要實現您希望定製類的消費者擁有的所有方法和屬性。

我已經命名爲自定義項目'項目',並實現了一個方法和一個屬性。 (對於不區分大小寫的VB也許Itemz會更好;-)

這裏是最小的人在這方面的中間人:

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

    public mimComboBox() 
    { 
     items_ = Items; 
    } 

} 

這裏是一個自定義組合框:

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

    那麼(3)就會編譯得很好。然而在運行時它會拋出一個空對象引用錯誤。

    這是缺少Overridable屬性的遲到效果嗎? @Jon Skeet來拯救! ;-)

+0

**非常有趣。部分這隻適用於C#;轉換爲VB(我在VB中更清楚地看到)Intellisence顯示並使用'.items_' - 這是因爲VB不區分大小寫,所以'items'不能替代'Items'。我做了一些調整,試圖讓它更實用。隨意添加/更改/忽略按需:http://pastebin.com/fSF6ZjTf – Plutonix

1

MyComboBox作爲正常的組合框(通過重寫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 

末級

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

    } 

} 
相關問題