2010-11-28 96 views
2

我正在使用自定义菜单控件,部分是作为学习练习,并且我在标记视图中遇到了Visual Studio对它的IntelliSense支持问题。自定义ASP.NET菜单控件

传统的ASP.NET菜单允许您在<Items>...</Items>元素下放置任意深度的<asp:MenuItem/>元素。我对我的菜单采取了同样的行为。

不幸的是我的不是。 VS坚持空标签:

<hn:AwesomeMenu runat="server" ID="menu"> 
    <Items /> 
</hn:AwesomeMenu> 

我已经使用反射来挖掘到ASP.NET菜单控制及其相关类(菜单项,MenuItemCollection和soforth),并确保我的类具有相同的接口和属性,所以我有点难以理解我要出错的地方。我的课的存根到目前为止如下:

AwesomeMenu.cs

public class AwesomeMenu 
    : HierarchicalDataBoundControl, 
     IPostBackEventHandler, 
     INamingContainer 
{ 
    [PersistenceMode(PersistenceMode.InnerProperty), 
    MergableProperty(false), 
    DefaultValue(default(string)), 
    Browsable(false)] 
    public AwesomeCollection Items 
    { 
     get { ... } 
    } 
} 

AwesomeCollection.cs

public class AwesomeCollection 
    : ICollection, 
     IEnumerable, 
     IStateManager 
{ ... } 

AwesomeItem.cs

[ParseChildren(true, "Children")] 
public class AwesomeItem 
    : IStateManager, 
     ICloneable 
{ 
    [PersistenceMode(PersistenceMode.InnerDefaultProperty), 
    MergableProperty(false)] 
    public AwesomeCollection Children 
    { 
     get { ... } 
    } 

    public AwesomeItem Parent 
    { 
     get { ... } 
    } 
} 

为简洁起见,省略了接口实现。任何帮助,将不胜感激。

回答

1

很大程度上得益于我迟到的博客文章(The ParseChildren PersistChildren and PersistenceMode.InnerProperty),我能够围绕上述属性的适当用法进行包装。

基本上我只需要菜单类本身的[ParseChildren(...)]属性。一个最小的成功实施所需的行为如下:

Menu.cs

[ParseChildren(ChildrenAsProperties = true)] 
public class Menu 
    : Control 
{ 
    [PersistenceMode(PersistenceMode.InnerProperty), 
    Browsable(false)] 
    public List<Item> Items { get; set; } 
} 

Item.cs

[ParseChildren(
    typeof(Item), 
    DefaultProperty = "Items", 
    ChildrenAsProperties = true)] 
public class Item 
{ 
    public string Text { get; set; } 

    [Browsable(false)] 
    public List<Item> Items { get; set; } 
} 

我唯一的问题是如何在ASP.NET菜单在不使用此属性的情况下实现相同的行为。