编程开发 > ASP > 文章内容

一个“简单”的ASP.NET的服务器控件(一)

2010-10-25编辑:dan

在我主持过的一个Asp.Net论坛上,一个用户询问如何在一个页面上去通过hyperlink列出一个路径下的很多文件名,能使用户能点击它们。我认为这是可能是经常执行的动作,所以决定建立一个服务器控件来封装它。

起初,我尝试了Web用户控件,但我想能允许设置边框,字体,背景颜色等。使用Web用户控件,我要为每一个属性手动设置。俗话说:“你写的代码越少,你的错误越少了”,所以我要研究一个更好的方法。

我决定创建自己首个自定义服务器控件。我试着去继承一个label控件,但label控件不支持滚动条。 所以,我选择继承Panel控件。最终的控件具有Panel控件的所有属性(颜色,边框,滚动支持等),再加上一些我添加自定义属性。使用Panel控件将会尽最小的努力。

第一部分:自定义服务器控件

初始化的服务器控制相对容易。下面是最终的代码:

以下为引用的内容:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.Web.UI;
using System.Web.UI.WebControls;

[assembly: TagPrefix("EndWell", "EW")]
namespace EndWell
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:HyperlinkFileList runat="server">")]
    [ToolboxBitmap("HyperlinkFileList.ico")]
    
    public class HyperlinkFileList : Panel
    {
        [Bindable(true)]
        [Category("Files List")]
        [Description("The Title of the list of files")]
        public string FilesTitle {get; set;}

        [Bindable(true)]
        [Category("Files List")]     
        [Description("The directory of the files to list:  (~/Files/)")]
        // these two built in editors were lacking:
        //[EditorAttribute(typeof(System.Web.UI.Design.UrlEditor), typeof(UITypeEditor))]
        //[EditorAttribute(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(UITypeEditor))]
        [EditorAttribute(typeof(EndWell.DualModeFolderEditor), typeof(UITypeEditor))]  
        public string FilesDirectory { get; set; }

        [Bindable(true)]
        [Category("Files List")]
        [Description("The filter for the files to show:  (*.*)")]
        public string FilesFilter { get; set; }

        [Bindable(true)]
        [Category("Files List")]
        [Description("Text to show when there are no files")]
        public string NoFilesText { get; set; }

        // ---- Private vars --------------------------

        private String[] m_FilesArray;  // cached for performance

        // ---- Default constants-------------------

        const String DEF_FILES_DIR = "~/xml/";
        const String DEF_FILES_FILT = "*.xml";
        const String DEF_FILES_TITLE = "XML Files:";
        const String DEF_NOFILES_TEXT = "";

        // ---- Constructor -------------------------- 

        public HyperlinkFileList()
        {
            // set defaults for our properties
            FilesDirectory = DEF_FILES_DIR;
            FilesFilter = DEF_FILES_FILT;
            FilesTitle = DEF_FILES_TITLE;
            NoFilesText = DEF_NOFILES_TEXT;

            // Set defaults for panel properties
            // I don't like the default width to be full screen
            // And a border looks better
            Width = new Unit("300px");
            BorderStyle = BorderStyle.Solid;
            BorderWidth = 1;
            BorderColor = Color.Black;

            // If height is set, force scroll bars to keep list
            // from spilling over the panel/div boundaries.
            if ((Height != null) && (ScrollBars == ScrollBars.None))
                ScrollBars = ScrollBars.Auto;
           
            // Allow multiple controls to be placed horizontally
            // (normally each div get's its own line)           
            Style["display"] = "inline-block";

            // add spacing outside the control
            Style["margin"] = "0.5em";

            // add space inside the control           
            Style["padding-left"] = "0.5em";
            Style["padding-right"] = "0.5em";
            Style["padding-bottom"] = "0.5em";
            // top space usually comes from the title...
            if (String.IsNullOrEmpty(FilesTitle) == true)
                Style["padding-top"] = "0.5em";
        }

        // ---- RenderContents ----------------------------
        //
        // Spit out the HTML
 
        protected override void RenderContents(HtmlTextWriter Output)
        {
            // output the title if one was set
            if (String.IsNullOrEmpty(FilesTitle) == false)
            {
                Output.Write("<h3>  ");  // cosmetic spacing
                Output.Write(FilesTitle);
                Output.Write("</h3>");
            }

            GetFilesArray();
  
            if (m_FilesArray.Length == 0)
            {
                Output.Write(HttpUtility.HtmlEncode(NoFilesText));              
            }
            else
            {
                foreach (String OneFile in m_FilesArray)
                {
                    HyperLink Link = new HyperLink();
                    Link.NavigateUrl = Path.Combine(FilesDirectory, Path.GetFileName(OneFile));
                    Link.Text = Path.GetFileNameWithoutExtension(OneFile);                  
                    Link.RenderControl(Output);
                    Output.WriteBreak();
                }
            }
        }

        // ---- GetFilesArray -------------------------
        //
        // Fill the m_FilesArray with a list of files
        // either from disk or the cache

        private void GetFilesArray()
        {
            // see if the file list is in the cache.
            // use directory and filter as unique key
            m_FilesArray = Page.Cache[FilesDirectory + FilesFilter] as String[];

            if (m_FilesArray != null)
                return;

            // if no files filter set, use the default one.
            if (String.IsNullOrEmpty(FilesFilter))
                FilesFilter = DEF_FILES_FILT;

            // if no files directory set, use the default one.
            if (String.IsNullOrEmpty(FilesDirectory))
                FilesDirectory = DEF_FILES_DIR;

            // if a virtual path is detected, map to full path
            String FullPath;
            if (FilesDirectory.StartsWith("~"))
                FullPath = Context.Server.MapPath(FilesDirectory);
            else
                FullPath = FilesDirectory;

            // get the files
            m_FilesArray = Directory.GetFiles(FullPath, FilesFilter, SearchOption.TopDirectoryOnly);
            
            // put the list in the cache so we don't have to read the disk again
            // use a dependency on the directory being read from for auto refreshing
            Page.Cache.Insert(FilesDirectory + FilesFilter,   // unique key
                              m_FilesArray,                   // list of files to store
                              new CacheDependency(FullPath)); // dependency on directory
           
        }
    }
}

ASP.NET实现类似Excel的数据透视表汇总

热点推荐

登录注册
触屏版电脑版网站地图