自定義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控件實例

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