• 发布一个比较粗糙的控件UpdownPanel


    前一段时间写了几篇关于控件开发的文章,一直没有一个实战的控件出来。年前的一个项目中,发现一个比较好的效果,后来为了方面开发,就开发成了一个容器控件。来看控件的几个效果图:

    运行效果图

    image image

    设计时的效果图

    image image

    控件的原理

    很显然控件的最外层是标签<fieldset></fieldset>,内容部分是包在内部的一个<div></div>里面的,通过控制div的display来实现效果的。大体的前台html结构:

    <fieldset>
          <legend>测试例子</legend>
                <div>
                     测试例子的内容
               </div>
    </fieldset>

    UpdownPanel的实现

    首先,确认UpdownPanel控件不需要继承某一个控件,但需要一些设计时的支持,如:边框的颜色、高、宽,所以可以确定控件继承于WebControl。控件标签的内容要解释成子控件,同时需要支持事件回传来通知是否已经打开,所以控件还需要继承IPostBackEventHandler。

    我们先来看控件的属性:


           
    /// <summary>
           
    /// 标题
           
    /// </summary>
            public string Title
            {
               
    get
                {
                   
    if (ViewState["Title"] == null)
                       
    return String.Empty;
                   
    return ViewState["Title"].ToString().Trim();
                }
               
    set
                {
                    ViewState[
    "Title"] = value;
                }
            }

           
    /// <summary>
           
    /// 距离左边距离
           
    /// </summary>
            public Unit PandingLeft
            {
               
    get
                {
                   
    if (ViewState["PandingLeft"] == null)
                       
    return new Unit("20px");
                   
    return new Unit(ViewState["PandingLeft"].ToString());
                }
               
    set
                {
                    ViewState[
    "PandingLeft"] = value;
                }
            }

           
    /// <summary>
           
    /// 距离上边距离
           
    /// </summary>
            public Unit PandingTop
            {
               
    get
                {
                   
    if (ViewState["PandingTop"] == null)
                       
    return new Unit("20px");
                   
    return new Unit(ViewState["PandingTop"].ToString());
                }
               
    set
                {
                    ViewState[
    "PandingTop"] = value;
                }
            }

           
    /// <summary>
           
    /// 是否打开
           
    /// </summary>
            [DefaultValue(false)]
           
    public bool IsOpen
            {
               
    get
                {
                   
    if (ViewState["IsOpen"] == null)
                       
    return false;
                   
    return Convert.ToBoolean(ViewState["IsOpen"]);
                }
               
    set
                {
                    ViewState[
    "IsOpen"] = value;
                }
            }

    Title属性是表示标题,IsOpen属性表示是否已经展开,属性都很简单。

    控件的事件参数类:

    /// <summary>
       
    /// IsOpenChanged事件的参数
       
    /// </summary>
        public class ChangedArgs : EventArgs
        {
           
    private bool _isOpened;

           
    public bool IsOpened
            {
               
    get
                {
                   
    return _isOpened;
                }
               
    set
                {
                    _isOpened
    = value;
                }
            }

           
    public ChangedArgs(bool bOpened)
            {
                IsOpened
    = bOpened;
            }
        }

    事件回传:

            static object _isOpenChanged = new object();

            
    public event EventHandler<ChangedArgs> IsOpenChanged
            {
                add
                {
                    Events.AddHandler(_isOpenChanged, value);
                }
                remove
                {
                    Events.RemoveHandler(_isOpenChanged, value);
                }
            }
            
             
    public void RaisePostBackEvent(string eventArgument)
            {
                ChangedArgs args 
    = new ChangedArgs(Convert.ToBoolean(eventArgument.ToString()));
                
    if (args.IsOpened)
                    IsOpen 
    = false;
                
    else
                    IsOpen 
    = true;
                
    if (Events[_isOpenChanged] != null)
                {
                    (Events[_isOpenChanged] 
    as EventHandler<ChangedArgs>)(null, args);
                }
            }

    控件的呈现时候,首先需要重写TagKey为"<filedset>",同时要注意注册事件回传的脚本,跟输出自己的控制脚本。这里就不列出所有的呈现的代码了,就看下关键的几行代码:

           protected override void RenderContents(HtmlTextWriter writer)
            {
                
    //呈现Legend
                writer.AddStyleAttribute(HtmlTextWriterStyle.FontStyle, this.Font.ToString());
                writer.AddStyleAttribute(HtmlTextWriterStyle.FontSize, 
    this.Font.Size.ToString());
                writer.AddStyleAttribute(HtmlTextWriterStyle.Cursor, 
    "pointer");
                
                
    //-------------加载事件回传------------------
                string strRef = Page.ClientScript.GetPostBackClientHyperlink(this,IsOpen.ToString());
                writer.AddAttribute(HtmlTextWriterAttribute.Href, strRef);
                writer.AddStyleAttribute(HtmlTextWriterStyle.TextDecoration, 
    "none");
                writer.RenderBeginTag(HtmlTextWriterTag.A);
                
                
    //标题
                writer.Write("&nbsp&nbsp&nbsp"+this.Title);
                writer.RenderEndTag();
                writer.RenderEndTag();
                writer.AddAttribute(HtmlTextWriterAttribute.Id, 
    "upChild" + this.ClientID);
                writer.AddStyleAttribute(HtmlTextWriterStyle.Height, 
    this.Height.ToString());
                
    //判断是否打开
                if (!this.IsOpen)
                {
                    writer.AddStyleAttribute(HtmlTextWriterStyle.Display, 
    "none");
                }
                writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingTop, 
    this.PandingTop.ToString());
                writer.RenderBeginTag(HtmlTextWriterTag.Div);
                
    //呈现子控件
                for (int i = 0; i < this.Controls.Count; i++)
                {
                    
    this.Controls[i].RenderControl(writer);
                }
                writer.RenderEndTag();
            }

    最后要注意的一点就是我们要让控件能够在设计时支持,还需要自定义一个ControlDesigner:

        public class UpDownPanelDesigner : System.Web.UI.Design.ContainerControlDesigner
        {
            
    public override string FrameCaption
            {
                
    get
                {
                    
    return "UpDownPanel的内容";
                }
            }
        }

    因为UpDownPanel控件是容器控件,所以我们继承于ContainerControlDesigner,同时需要在控件上标识:

       [Designer(typeof(UpDownPanelDesigner))]
        
    public class UpDownPanle:WebControl,IPostBackEventHandler
        {

        }

    这下就可以使用了,只不过控件还比较粗糙,在以后会逐步完善,还请大家批评,呵呵。

    【示例及dll下载地址】

    作者:Henllyee Cui
    出处: http://henllyee.cnblogs.com/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。
  • 相关阅读:
    第五届“飞思卡尔”智能车竞赛分赛区赛后总结
    最佳编程语录
    通过UserAgent判断智能手机(设备,Android,IOS)
    Sql Server 系统存储过程分析 2 数据库引擎存储过程
    OutputCache 导致页面下载的解决办法
    w3wp.exe(IIS ) CPU 占用 100% 的常见原因及解决办法
    过滤并替换页面html输出
    Sql Server 系统存储过程分析 1 目录存储过程
    Sql Server 监控 Job 执行情况
    OutPutCache 自定义缓存:session、登录用户、cookie 等
  • 原文地址:https://www.cnblogs.com/Henllyee/p/1381922.html
Copyright © 2020-2023  润新知