2012-03-26 109 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”标记版本,这会导致只有在调用方明确知道对象时才使用该方法的版本你的新班级类型。 这取决于你的需要,但前者更常见。