代码之家  ›  专栏  ›  技术社区  ›  Mohammad Dayyan

在ASP.NET中创建ServerControl时出现问题,C?

  •  1
  • Mohammad Dayyan  · 技术社区  · 14 年前

    我在做一个ServerControl(超级菜单)。
    下面是我的代码。

    菜单.cs

    [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [ParseChildren(true, "MenuItems")]
    [PersistChildren(true)]
    [ToolboxData("<{0}:Menu runat=\"server\"></{0}:Menu>")]
    public class Menu : WebControl, INamingContainer
    {
        #region Fields
    
        List<MenuItem> _MenuItems;
    
        #endregion
    
        #region Properties
    
        public VerOrHor VerticalOrHorizontal { get; set; }
    
        public string Main_ul_CssClass { get; set; }
    
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public animation AnimationItems { get; set; }
    
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public List<MenuItem> MenuItems
        {
            get
            {
                if (_MenuItems == null)
                {
                    _MenuItems = new List<MenuItem>();
                }
                return _MenuItems;
            }
        }
    
        string _AnimationType
        {
            get
            {
                switch (this.AnimationItems.AnimationType)
                {
                    case AnimationType.Opacity_Height:
                        return "animation:{opacity:'show',height:'show'}";
                    case AnimationType.Opacity:
                        return "animation:{opacity:'show'}";
                    case AnimationType.Height:
                        return "animation:{height:'show'}";
                    default:
                        return "animation:{opacity:'show',height:'show'}";
                }
            }
        }
    
        string _AnimationSpeed
        {
            get
            {
                switch (this.AnimationItems.AnimationSpeed)
                {
                    case AnimationSpeed.Fast:
                        return "speed:Fast";
                    case AnimationSpeed.Normal:
                        return "speed:Normal";
                    case AnimationSpeed.Slow:
                        return "speed:Slow";
                    default:
                        return "speed:Fast";
                }
            }
        }
    
        #endregion
    
        #region Methods
    
        public override void RenderBeginTag(HtmlTextWriter writer)
        {
    
        }
    
        public override void RenderEndTag(HtmlTextWriter writer)
        {
    
        }
    
        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {
            base.AddAttributesToRender(writer);
        }
    
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
    
            #region Adding Script & link Tags
    
            HtmlGenericControl jquery = new HtmlGenericControl("script");
            jquery.Attributes.Add("type", "text/javascript");
            jquery.Attributes.Add("src", Page.ClientScript.GetWebResourceUrl(typeof(Menu), "JQueryMenu.JavaScriptFiles.jquery_1_4_3.js"));
            jquery.EnableViewState = false;
            Page.Header.Controls.Add(jquery);
    
            HtmlGenericControl hoverIntent = new HtmlGenericControl("script");
            hoverIntent.Attributes.Add("type", "text/javascript");
            hoverIntent.Attributes.Add("src", Page.ClientScript.GetWebResourceUrl(typeof(Menu), "JQueryMenu.JavaScriptFiles.hoverIntent.js"));
            hoverIntent.EnableViewState = false;
            Page.Header.Controls.Add(hoverIntent);
    
            HtmlGenericControl jquery_bgiframe_min = new HtmlGenericControl("script");
            jquery_bgiframe_min.Attributes.Add("type", "text/javascript");
            jquery_bgiframe_min.Attributes.Add("src", Page.ClientScript.GetWebResourceUrl(typeof(Menu), "JQueryMenu.JavaScriptFiles.jquery_bgiframe_min.js"));
            jquery_bgiframe_min.EnableViewState = false;
            Page.Header.Controls.Add(jquery_bgiframe_min);
    
            HtmlGenericControl superfish = new HtmlGenericControl("script");
            superfish.Attributes.Add("type", "text/javascript");
            superfish.Attributes.Add("src", Page.ClientScript.GetWebResourceUrl(typeof(Menu), "JQueryMenu.JavaScriptFiles.superfish.js"));
            superfish.EnableViewState = false;
            Page.Header.Controls.Add(superfish);
    
            HtmlGenericControl supersubs = new HtmlGenericControl("script");
            supersubs.Attributes.Add("type", "text/javascript");
            supersubs.Attributes.Add("src", Page.ClientScript.GetWebResourceUrl(typeof(Menu), "JQueryMenu.JavaScriptFiles.supersubs.js"));
            supersubs.EnableViewState = false;
            Page.Header.Controls.Add(supersubs);
    
            HtmlGenericControl csslink = new HtmlGenericControl("link");
            csslink.Attributes.Add("href", Page.ClientScript.GetWebResourceUrl
                (typeof(Menu), "JQueryMenu.CSS.superfish.css"));
            csslink.ID = "NavigationMenu";
            csslink.Attributes.Add("type", "text/css");
            csslink.Attributes.Add("rel", "stylesheet");
            csslink.EnableViewState = false;
            Page.Header.Controls.Add(csslink);
    
            if (this.VerticalOrHorizontal == VerOrHor.Vertical)
            {
                HtmlGenericControl csslink01 = new HtmlGenericControl("link");
                csslink01.Attributes.Add("href", Page.ClientScript.GetWebResourceUrl
                    (typeof(Menu), "JQueryMenu.CSS.superfish-vertical.css"));
                csslink01.Attributes.Add("type", "text/css");
                csslink01.Attributes.Add("rel", "stylesheet");
                csslink01.EnableViewState = false;
                Page.Header.Controls.Add(csslink01);
            }
    
            #endregion
        }
    
        protected override void RenderContents(HtmlTextWriter output)
        {
            output.Write(CreateMenuHtmlTags().ToString());
        }
    
        StringBuilder CreateMenuHtmlTags()
        {
            if (_MenuItems == null || _MenuItems.Count <= 0)
                throw new Exception("Please Fill the control with <MenuItem> tags");
    
            StringBuilder Html = new StringBuilder("");
    
            #region Add <Script>
    
            if (String.IsNullOrEmpty(Main_ul_CssClass))
                Html.Append("<script>$(document).ready(function() { $(\"ul.sf-menu\").superfish({pathLevels:    1,");
            else
                Html.Append("<script>$(document).ready(function() { $(\"ul." + Main_ul_CssClass + "\").superfish({ pathLevels:    1,");
    
            if (AnimationItems == null)
                Html.Append("delay:1000, animation:{opacity:'show',height:'show'}, speed:'normal', autoArrows:  true, dropShadows: true}); });</script>");
            else
            {
                Html.Append("delay:" + AnimationItems.Delay.Trim() + ",");
                Html.Append(_AnimationType + ",");
                Html.Append(_AnimationSpeed + ",");
                Html.Append("dropShadows:  " + AnimationItems.DropShadow.ToString() + ",");
                Html.Append(@"autoArrows:  false});});</script>");
            }
    
            #endregion
    
            if (String.IsNullOrEmpty(Main_ul_CssClass))
                Html.Append("<ul class=\"sf-menu sf-js-enabled sf-shadow\" id='sample-menu-1'>");
            else
                Html.Append("<ul class=\"" + Main_ul_CssClass + "\" id='sample-menu-1'>");
    
            foreach (MenuItem item in _MenuItems)
            {
                if (item.SubMenuItems != null || item.SubMenuItems.Count > 0)
                {
                    if (!string.IsNullOrEmpty(item.li_CssClass))
                        Html.Append("<li class=\"" + item.li_CssClass + "\">");
                    else
                        Html.Append("<li>");
                    Html.Append("<a href=\"" + item.href + "\">" + item.Text.Trim() + "</a>");
                    ParseSubMenuItems(ref Html, item);
                    Html.Append("</li>");
                }
                else
                    Html.Append("<li><a href=\"" + item.href + "\">" + item.Text.Trim() + "</a></li>");
            }
            Html.Append("</ul>");
    
            return Html;
        }
    
        void ParseSubMenuItems(ref StringBuilder Html, MenuItem menuItems)
        {
            if (menuItems == null || menuItems.SubMenuItems.Count == 0) return;
    
            Html.Append("<ul class=\"" + menuItems.ul_CssClass.Trim() + "\" style=\"display: none; visibility: hidden;\">");
            foreach (MenuItem item in menuItems.SubMenuItems)
            {
                if (item.SubMenuItems != null || item.SubMenuItems.Count > 0)
                {
                    if (!string.IsNullOrEmpty(item.li_CssClass))
                        Html.Append("<li class=\"" + item.li_CssClass + "\">");
                    else
                        Html.Append("<li>");
                    Html.Append("<a href=\"" + item.href + "\">" + item.Text.Trim() + "</a>");
                    ParseSubMenuItems(ref Html, item);
                    Html.Append("</li>");
                }
                else
                    Html.Append("<li><a href=\"" + item.href + "\">" + item.Text.Trim() + "</a></li>");
            }
            Html.Append("</ul>");
        }
    
        #endregion
    }
    
    public enum VerOrHor
    {
        Vertical,
        Horizontal
    }
    
    public class MenuItemsCollectionEditor : CollectionEditor
    {
        public MenuItemsCollectionEditor(Type type)
            : base(type)
        {
        }
    
        protected override bool CanSelectMultipleInstances()
        {
            return false;
        }
    
        protected override Type CreateCollectionItemType()
        {
            return typeof(MenuItem);
        }
    }
    

    菜单项.cs

    [PersistChildren(true)]
    [ParseChildren(true, "SubMenuItems")]
    public class MenuItem : Control, INamingContainer
    {
        #region Fields
    
        List<MenuItem> _SubMenuItems;
    
        #endregion
    
        #region Properties
    
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        //[Editor(typeof(SubMenuItemsCollectionEditor), typeof(UITypeEditor))]
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public List<MenuItem> SubMenuItems
        {
            get
            {
                if (_SubMenuItems == null)
                {
                    _SubMenuItems = new List<MenuItem>();
                }
                return _SubMenuItems;
            }
        }
    
        [DefaultValue("MenuItem")]
        public string Text { get; set; }
    
        [DefaultValue("")]
        [Description("<ul /> css class")]
        public string ul_CssClass { get; set; }
    
        [DefaultValue("")]
        [Description("<li /> css class")]
        public string li_CssClass { get; set; }
    
        [DefaultValue("#")]
        [Description("<a /> href attribute")]
        public string href { get; set; }
    
        [TemplateContainer(typeof(MenuItem))]
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public ITemplate Template { get; set; }
    
        #endregion
    }
    
    public class SubMenuItemsCollectionEditor : CollectionEditor
    {
        public SubMenuItemsCollectionEditor(Type type)
            : base(type)
        {
        }
    
        protected override bool CanSelectMultipleInstances()
        {
            return false;
        }
    
        protected override Type CreateCollectionItemType()
        {
            return typeof(MenuItem);
        }
    }
    

    动画.cs

    public class animation
    {
        [DefaultValue("1000")]
        [NotifyParentProperty(true)]
        public string Delay { get; set; }
    
        [DefaultValue("Opacity_Height")]
        [NotifyParentProperty(true)]
        public AnimationType AnimationType { get; set; }
    
        [DefaultValue("fast")]
        [NotifyParentProperty(true)]
        public AnimationSpeed AnimationSpeed { get; set; }
    
        [DefaultValue("false")]
        [NotifyParentProperty(true)]
        public bool DropShadow { get; set; }
    }
    
    public enum AnimationType
    {
        Opacity_Height,
        Opacity,
        Height
    }
    
    public enum AnimationSpeed
    {
        Fast,
        Normal,
        Slow
    }
    

    使用以下代码(无 AnimationItems ):

    <MdsMenu:Menu ID="Menu1" runat="server">
        <MdsMenu:MenuItem Text="MenuItem 01"></MdsMenu:MenuItem>
        <MdsMenu:MenuItem Text="MenuItem 02"></MdsMenu:MenuItem>
        <MdsMenu:MenuItem Text="MenuItem 03" />
    </MdsMenu:Menu>
    

    但当我加上 动画项 像下面的代码这样的标签,我收到异常:

    异常:创建控件时出错-menu1类型“jquerymenu.menu”没有名为“menuitem”的公共属性。

    Error Creating Control

    <MdsMenu:Menu ID="Menu1" runat="server">
        <AnimationItems AnimationSpeed="Fast" AnimationType="Opacity_Height" DropShadow="true" Delay="1000" />
        <MdsMenu:MenuItem Text="MenuItem 01"></MdsMenu:MenuItem>
        <MdsMenu:MenuItem Text="MenuItem 02"></MdsMenu:MenuItem>
        <MdsMenu:MenuItem Text="MenuItem 03" />
    </MdsMenu:Menu>
    
    1 回复  |  直到 14 年前
        1
  •  1
  •   Frédéric Hamidi    14 年前

    你有两处房产 PersistenceMode.InnerDefaultProperty ,以及:

    只能指定一个属性 默认属性。

    我建议你装饰一下 AnimationItems 属性 PersistenceMode.InnerProperty 相反:

    [PersistenceMode(PersistenceMode.InnerProperty)]
    public animation AnimationItems
    {
        get;
        set;
    }
    

    编辑: 以上还不够。我让代码进行一些调整:

    首先,禁用子持久性并删除 defaultProperty 来自的参数 [ParseChildren] 属性:

    [AspNetHostingPermission(SecurityAction.Demand,
        Level = AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand,
        Level = AspNetHostingPermissionLevel.Minimal)]
    [ParseChildren(true)]
    [ToolboxData("<{0}:Menu runat=\"server\"></{0}:Menu>")]
    public class Menu : WebControl, INamingContainer
    {
    }
    

    然后,装饰 动画项 属性 PersistenceMode.InnerProperty ,如上所述。对…做同样的事 MenuItems 并将其移除 [DesignerSerializationVisibility] 属性:

    [PersistenceMode(PersistenceMode.InnerProperty)]
    public animation AnimationItems { get; set; }
    
    [PersistenceMode(PersistenceMode.InnerProperty)]
    public List<MenuItem> MenuItems
    {
    }
    

    最后,添加 <MenuItems> 标记的元素:

    <MdsMenu:Menu ID="Menu1" runat="server">
        <AnimationItems AnimationSpeed="Fast" AnimationType="Opacity_Height"
            DropShadow="true" Delay="1000" />
        <MenuItems>
            <MdsMenu:MenuItem Text="MenuItem 01"></MdsMenu:MenuItem>
            <MdsMenu:MenuItem Text="MenuItem 02"></MdsMenu:MenuItem>
            <MdsMenu:MenuItem Text="MenuItem 03" />
        </MenuItems>
    </MdsMenu:Menu>
    
    推荐文章