2012-03-26 107 views
0

我想擴展TreeViewItem來添加一個屬性。使它複雜化的是它有一個「Items」屬性,它是一個相同類類型的列表。添加一個屬性將需要我重寫我不想做的子屬性。這是原始TreeViewItem:如何在不重寫的情況下向類添加屬性?

public class TreeViewItem : NavigationItem<TreeViewItem>, INavigationItemContainer<TreeViewItem>, ITreeViewItem 
{ 
    public IList<TreeViewItem> Items { get; } 
} 

如何添加MyProperty而不被強制覆蓋「Items」屬性。很多事情發生在我不想重新創建的「Items」屬性中。感謝您的任何幫助或建議。

+0

這個問題不是很清楚。如果添加名爲MyProperty的屬性,則既不會覆蓋也不會隱藏現有的Items屬性。你爲什麼認爲你會被迫改寫'Items'? – phoog 2012-03-26 21:20:49

+0

因爲我希望Items的子項具有新的MyProperty。否則,只有最高級別的根父級才具有該屬性。 – TruMan1 2012-03-26 21:22:30

+0

啊哈,我明白了。答案即將出爐。 – phoog 2012-03-26 21:23:55

回答

2

正如JaredPar建議的那樣,您可以使用new IList<MyExtendedTreeViewItem> Items屬性隱藏Items屬性。這不會替代基類的Items屬性,因此您必須同步它們。你可以通過實施(私有或內部)來實現這個目的來包裝基類的項目集合:

class ItemsWrapper : IList<MyExtendedTreeViewItem> 
{ 
    private IList<TreeViewItem> _baseItems; 

    public ItemsWrapper(IList<TreeViewItem> baseItems) 
    { 
     _baseItems = baseItems; 
    } 

    public void Add(MyExtendedTreeViewItem item) 
    { 
     _baseItems.Add(item); 
    } 

    // much of implementation omitted here for brevity 

    public MyExtendedTreeViewItem this[int index] 
    { 
     get { return (MyExtendedTreeViewItem)_baseItems[index]; } 
     set { _baseItems[index] = value; } 
    } 
} 

和:

class MyExtendedTreeViewItem : TreeViewItem 
{ 
    private ItemsWrapper _items; 

    public MyExtendedTreeViewItem() 
    { 
     _items = new ItemsWrapper(base.Items); 
    } 

    public new IList<MyExtendedTreeViewItem> Items { get { return _items; } } 
} 

這不完全是類型安全的,因爲有人可能會得到一個參考到基本項目屬性,然後添加一個TreeViewItem它,並投到MyExtendedTreeViewItem會引發異常。

+0

它在「set {_baseItems [index] = this」上窒息。它說不能將ItemsWrapper轉換爲TreeViewItem。似乎我可以拋棄但不起來。 – TruMan1 2012-03-26 22:33:58

+0

@ TruMan1這是我粗心大意的打字。它應該是'value'而不是'this'。我編輯了這篇文章。 – phoog 2012-03-26 22:37:59

3

這聽起來像你想用一個具有非常不同定義的屬性替換Items屬性。如果是這樣那麼使用new

public class MyItem : TreeViewItem { 
    public new List<SomethingElse> Items { 
    get { ... } 
    } 
} 

一般使用new被認爲是不好的做法。有些情況下,它是必要/有用的,但總的來說,它是不受歡迎的。更多特定的命名屬性往往是這種類型的行爲

1

的一個很好的中間地帶,您可以使用擴展方法的屬性,像這樣:

public static class TreeViewItemExtensions 
{ 
    public static object GetPropertyValue(this TreeViewItem tvi) 
    { 
    } 
} 

無需重寫任何東西,並用一種​​新的方法「擴展」你的TreeViewItem

希望這會有所幫助。

+0

關於如何「堅持」新的價值觀的任何想法? – TruMan1 2012-03-26 21:02:59

+0

@ TruMan1:如果你想要堅持不懈,'擴展方法'是不行的。要清楚它可以管理,但它是有線的,即時通訊。在這種情況下重寫'TreeViewItem'並實現你需要的屬性會更好。 – Tigran 2012-03-26 21:06:06

0

要麼覆蓋它並在頂部/底部調用base.Items,要麼使用關鍵字「new」標記版本,這會導致只有在調用方明確知道對象時才使用該方法的版本你的新班級類型。 這取決於你的需要,但前者更常見。