自定义asp.net控件开发之(五)-UpdownPanel控件实例

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

运行效果图

image image

 

设计时的效果图

image image

控件的原理

很显然控件的最外层是标签

,内容部分是包在内部的一个
里面的,通过控制div的display来实现效果的。大体的前台html结构:

UpdownPanel的实现

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

我们先来看控件的属性:


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

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

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

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

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

控件的事件参数类:

 

/// 
    
/// IsOpenChanged事件的参数
    
/// 
    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为"",同时要注意注册事件回传的脚本,跟输出自己的控制脚本。这里就不列出所有的呈现的代码了,就看下关键的几行代码:

 

       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
    {

    }

 

 

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

自定义asp.net控件开发系列链接:

自定义asp.net控件开发之(一)-显示控件内容

自定义asp.net控件开发之(二)-增加属性

自定义asp.net控件开发之(三)-标签间内容处理

自定义asp.net控件开发之(四)-数据回传

自定义asp.net控件开发之(五)-UpdownPanel控件实例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章