All articles| All Pictures| All Softwares| All Video| Go home page| Write articles| Upload pictures

Reading number is top 10 articles
系统恢复后,通过sqlserver服务管理器启动出现“指定的服务未安装”的解决方法_[SQL,Server教程]
曹操子孙聚沈阳,家谱难成_网络推广_编程技术
web标准实现高效开发_[Html教程]
GridView中利用隐藏的TemplateFied来进行数据访问_[Asp.Net教程]
PHP程序指定目录里的指定后缀名文件为超连接_php资料_编程技术
用C#访问ACCESS数据库问题_.net资料_编程技术
visual c++定制状态栏
温故知新ASP.NET,2.0(C#)系列文章索引_[Asp.Net教程]
ASP.NET从零起步设计网站全过程(9)_[Asp.Net教程]
基础知识之认识和使用,RSS+asp.net_[Asp.Net教程]
Reading number is top 10 pictures
Small QiShu -- ShuangShuangPan2
Exquisite decoration is not paying too much1
Summer is most suitable for young people to travel in China9
The money of more than 100 countries and regions10
梦幻的风景
2012 national geographic daily picture7
Absolutely shocked. National geographic 50 animal photographys3
mythology hero1
Beauty ZhiHuiLin2
NeedWallpaper4
Download software ranking
Unix video tutorial6
美女写真1
仙剑奇侠传98版歌曲
C++编程教程第三版
美女游泳记
Visual C++界面编程技术
Eclipse 4.2.2 For Win64
jdk1.6 for windows
matrix1
linux初级教程
delv published in(发表于) 2014/1/8 7:01:45 Edit(编辑)
ASP.NET2.0服务器控件之类型化样式属性_[Asp.Net教程]

ASP.NET2.0服务器控件之类型化样式属性_[Asp.Net教程]

ASP.NET2.0服务器控件之类型化样式属性_[Asp.Net教程]

 上一篇文章对控件样式属性的基本概念进行了介绍,同时,还通过示例说明了重写样式属性的方法。本文重点对类型化样式属性的创建方法进行讲解。

  实现类型化样式属性的方法

  继承自Style类的类称为类型化样式。Style类可以由控件开发人员来扩展,创建一个自定义类型化样式,它重写或者添加Style类的属性。服务器控件也可以把自定义类型化样式作为ControlStyle属性的类型。例如,Table控件的ControlStyle属性就是TableStyle类型,该类型是扩展的Style,添加了例如CellPadding、CellSpacing和GridLines属性等。在初步了解类型化样式属性的基本概念之后,下面列举了实现类型化样式属性的方法要点。

  (1)创建一个派生自System.Web.UI.WebControls.Style的类;

  (2)定义样式将为控件提供的属性。在Style的ViewState字典中保存该属性;

  (3)重写CopyFrom和MergeWith方法,从定义的属性中复制或者将定义的属性和一个给定样式的属性合并;

  (4)重写Reset方法,删除添加到ViewState中的属性;

  (5)重写AddAttributesToRender方法,产生HTML和CSS特性,作为控件呈现过程的一部分。

  实际上,创建类型化样式属性并不是一个简单的过程。为此,下面我们将通过典型应用示例来说明创建的具体方法,以便读者加深对于实现要点的理解。

  典型应用

  本节通过创建一个MyPanel控件以及相关联的类型化样式MyPanelStyle,来讲解如何实现并使用自定义类型化样式。就功能而言,MyPanel与ASP.NET 2.0内置的Panel控件是一致。开发人员可以通过把需要添加的控件嵌套在控件的标签中,向Controls集合中添加控件。在可视化设计器中,把所需添加的控件拖放到Panel的设计界面上,就可以把控件添加到Controls集合中。然而,MyPanel并不是从Panel类继承而来,而是自定义实现的结果,同时,该控件还提供了类型化样式属性MyPanelStyle,其中设置了3个样式属性:

  (1)BackImageUrl,用于指定背景图片的URL;

  (2)HorizontalAlign,用于指定所添加内容的水平对其方式;

  (3)Wrap,用于指定是否允许对所添加的内容换行。

  下面列举了示例效果图。



图1


  如图1所示,图中显示了一个MyPanel控件,其中包括一行文字,文字的背景图像已经定义,并且文字处于居中位置。

  下面列举了实现自定义服务器控件的MyPanel.cs源代码。


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebControlLibrary{
 [ ParseChildren(false), PersistChildren(true) ]
 [ToolboxData("<{0}:MyPanel runat=server></{0}:MyPanel>")]

 public class MyPanel : WebControl {
  // 定义构造函数
  public MyPanel() : base(HtmlTextWriterTag.Div) { }
  // 实现属性BackImageUrl
  [Bindable(true)] [Category("Appearance")]
  [DefaultValue("")]

  public virtual string BackImageUrl {
   get {
    if (ControlStyleCreated) {
     return ((MyPanelStyle)ControlStyle).BackImageUrl;
    }
    return String.Empty;
   }
   set {
     ((MyPanelStyle)ControlStyle).BackImageUrl = value;
   }
  }
  // 实现属性HorizontalAlign
  [Bindable(true)]
  [Category("Layout")]
  [DefaultValue("")]

  public virtual HorizontalAlign HorizontalAlign {
   get {
    if (ControlStyleCreated) {
     return ((MyPanelStyle)ControlStyle).HorizonalAlign;
    }
    return HorizontalAlign.NotSet;
   }
   set {
    ((MyPanelStyle)ControlStyle).HorizonalAlign = value;
   }
  }
  // 实现属性Wrap

  [Bindable(true)]
  [Category("Layout")]
  [DefaultValue("")]

  public virtual bool Wrap {
   get {
    if (ControlStyleCreated) {
     return ((MyPanelStyle)ControlStyle).Wrap;
    }
    return true;
   }
   set {
    ((MyPanelStyle)ControlStyle).Wrap = value;
   }
  }
  protected override Style CreateControlStyle() {
   return new MyPanelStyle(ViewState);
  }
 }
}

  在分析之前,为了帮助读者更好的阅读以上源代码,下面列举了MyPanel类图。



图2


  如上代码所示,MyPanel继承自WebControl基类,其中定义了3个属性BackImageUrl、HorizontalAlign和Wrap。关于这3个属性的说明,读者可参考前面的内容。另外,MyPanel重写了CreateControlStyle方法,返回一个MyPanelStyle对象。这样返回的MyPanelStyle实例间接的赋值给ControlStyle属性。这种实现方法的原因是由于ControlStyle属性是只读属性,且它的访问操作需要调用CreateControlStyle方法时间接进行设置。需要读者注意的是,CreateControlStyle将MyPanel控件的ViewState传递给MyPanelStyle的构造函数。当在CreateControlStyle中为控件创建新样式时,必须将控件的ViewState传给Style构造函数,那么样式对象则使用和控件相同的StateBag。

  下面列举了实现MyPanelStyle类的源代码,它们来自MyPanelStyle.cs文件。


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebControlLibrary{
 public class MyPanelStyle : Style {
  // 定义内部常量
  internal const int PROP_BACKIMAGEURL = 1;
  internal const int PROP_HORIZONTALALIGN = 2;
  internal const int PROP_WRAP = 3;
  //构造函数一
  public MyPanelStyle() { }
  // 构造函数二
  public MyPanelStyle(StateBag bag) : base(bag) { }
  // 创建BackImageUrl属性
  [ Bindable(true), Category("Appearance"), DefaultValue(""), Description("背景图片的URL"), NotifyParentProperty(true) ]
  public virtual string BackImageUrl {
   get {
    if (IsSet(PROP_BACKIMAGEURL)) {
     return (string)ViewState["BackImageUrl"];
    }
    return String.Empty;
   }
   set {
    ViewState["BackImageUrl"] = value;
   }
  }
  // 实现HorizonalAlign属性
  [ Bindable(true), Category("Layout"), DefaultValue(HorizontalAlign.NotSet), Description("所添加内容的水平对其方式"), NotifyParentProperty(true) ]
  public virtual HorizontalAlign HorizonalAlign {
   get {
    if (IsSet(PROP_HORIZONTALALIGN)) {
     return (HorizontalAlign)ViewState["HorizontalAlign"];
    }
    return HorizontalAlign.NotSet;
   }
   set {
    if (value < HorizontalAlign.NotSet || value > HorizontalAlign.Justify) {
     throw new ArgumentOutOfRangeException("value");
    }
    ViewState["HorizontalAlign"] = value;
   }
  }
  // 实现IsEmpty
  protected new internal bool IsEmpty {
   get {
    return base.IsEmpty && !IsSet(PROP_BACKIMAGEURL) && !IsSet(PROP_HORIZONTALALIGN) && !IsSet(PROP_WRAP);
   }
  }
  //实现Wrap属性
  [ Bindable(true), Category("Layout"), DefaultValue(true), Description("是否允许对所添加的内容换行"), NotifyParentProperty(true) ]
  public virtual bool Wrap {
   get {
    if (IsSet(PROP_WRAP)) { return (bool)ViewState["Wrap"]; }
    return true;
   }
   set { ViewState["Wrap"] = value; }
  }
  //辅助方法IsSet
  internal bool IsSet(int propNumber) {
   string key = null;
   switch (propNumber) {
    case PROP_BACKIMAGEURL: key = "BackImageUrl";
     break;
    case PROP_HORIZONTALALIGN: key = "HorizontalAlign";
     break;
    case PROP_WRAP: key = "Wrap";
     break;
   }
   if (key != null) {
    return ViewState[key] != null;
   }
   return false;
  }
  //重写AddAttributesToRender方法
  public override void AddAttributesToRender(HtmlTextWriter writer, WebControl owner) {
   if (IsSet(PROP_BACKIMAGEURL)) {
    string s = BackImageUrl;
    if (s.Length > 0) {
     if (owner != null) {
      s = owner.ResolveUrl(s);
     }
     writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, "url(" + s + ")");
    }
   }
   if (IsSet(PROP_HORIZONTALALIGN)) {
    System.Web.UI.WebControls.HorizontalAlign hAlign = this.HorizonalAlign;
    if (hAlign != System.Web.UI.WebControls.HorizontalAlign.NotSet) {
     TypeConverter hac = TypeDescriptor.GetConverter(typeof(HorizontalAlign));
     writer.AddAttribute(HtmlTextWriterAttribute.Align, hac.ConvertToInvariantString(hAlign));
    }
   }
   if (IsSet(PROP_WRAP)) {
    bool wrap = Wrap;
    if (!Wrap) {
     writer.AddAttribute(HtmlTextWriterAttribute.Nowrap, "nowwrap");
    }
   }
   base.AddAttributesToRender(writer, owner);
  }
  //重写CopyFrom方法
  public override void CopyFrom(Style s) {
   if (s != null) {
    base.CopyFrom(s);
    if (s is MyPanelStyle) {
     MyPanelStyle mps = (MyPanelStyle)s;
     if (!mps.IsEmpty) {
      if (mps.IsSet(PROP_BACKIMAGEURL))
       this.BackImageUrl = mps.BackImageUrl;
      if (mps.IsSet(PROP_HORIZONTALALIGN))
       this.HorizonalAlign = mps.HorizonalAlign;
      if (mps.IsSet(PROP_WRAP))
       this.Wrap = mps.Wrap;
     }
    }
   }
  }
  // 重写MergeWith方法
  public override void MergeWith(Style s) {
   if (s != null) {
    if (IsEmpty) {
     CopyFrom(s);
     return;
    }
    base.MergeWith(s);
    if (s is MyPanelStyle) {
     MyPanelStyle mps = (MyPanelStyle)s;
     if (!mps.IsEmpty) {
      if (mps.IsSet(PROP_BACKIMAGEURL) && !this.IsSet(PROP_BACKIMAGEURL))
       this.BackImageUrl = mps.BackImageUrl;
      if (mps.IsSet(PROP_HORIZONTALALIGN) && !this.IsSet(PROP_HORIZONTALALIGN))
       this.HorizonalAlign = mps.HorizonalAlign;
      if (mps.IsSet(PROP_WRAP) && !this.IsSet(PROP_WRAP))
       this.Wrap = mps.Wrap;
     }
    }
   }
  }
  //重写Reset方法
  public override void Reset() {
   base.Reset();
   if (IsEmpty) return;
   if (IsSet(PROP_BACKIMAGEURL))
    ViewState.Remove("BackImageUrl");
   if (IsSet(PROP_HORIZONTALALIGN))
    ViewState.Remove("HorizontalAlign");
   if (IsSet(PROP_WRAP)) ViewState.Remove("Wrap");
  }
 }
}

  下面列举了MyPanelStyle类图。



图3


  可能部分读者感觉MyPanelStyle类实现有些复杂,然而,还是有据可寻的。该类的实现严格按照前文所述的类型化样式属性创建方法来进行。

  首先,MyPanelStyle类继承了Style类,这是创建类型化样式属性的关键,接着定义了3个属性BackImageUrl、HorizontalAlign和Wrap。这3个属性支持MyPanel中对应的样式属性。然后,代码重写了AddAttributesToRender方法,以便当控件呈现时准确生成相关的HTML和CSS代码。需要注意的是,该方法的第二个参数不可为空,其表示拥有Style对象的具体控件。最后,代码中重写了3个来自Style的方法,CopyFrom、MergeWith和Reset。重写前两个方法是为了复制给定的MyPanelStyle或者把给定的MyPanelStyle与自身合并。这两个方法都调用了基类方法,然后执行自身的逻辑。重写Reset方法主要目的是为了删除添加到ViewState中的属性,它的实现思路与前两个方法差不多,都是调用基类方法,然后执行自身逻辑。

  下面列举了为测试MyPanel控件而创建的Default.aspx文件源代码。


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register TagPrefix="wcl" Assembly="WebControlLibrary" Namespace="WebControlLibrary" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>类型化样式属性</title>
</head>
<body>
<form id="form1" runat="server">
<wcl:MyPanel ID="demo1" runat="server" BackImageUrl="pic1.jpg" HorizontalAlign="Center" Height="145" Width="160">
<br />
<br />
这是一行位于MyPanel控件中的文字。
</wcl:MyPanel>
</form>
</body>
</html>

  如上代码所示,开发人员可以像使用Panel控件一样,将需要添加的控件设置在MyPanel标签中。这样所设置的控件将自动的显示出来,并且由于MyPanel控件自身的属性设置,其显示的外观和样式将发生相应变化。

  小结

  本文针对类型化样式属性的实现方法进行了介绍,并且通过一个典型示例加强了读者对于实现方法的理解。在接下来的文章中,我们将继续讨论利用ASP.NET 2.0技术,实现控件客户端功能的内容。
作者:金属边缘 来源:天极开发





添加到del.icio.us 添加到新浪ViVi 添加到百度搜藏 添加到POCO网摘 添加到天天网摘365Key 添加到和讯网摘 添加到天极网摘 添加到黑米书签 添加到QQ书签 添加到雅虎收藏 添加到奇客发现 diigo it 添加到饭否 添加到飞豆订阅 添加到抓虾收藏 添加到鲜果订阅 digg it 貼到funP 添加到有道阅读 Live Favorites 添加到Newsvine 打印本页 用Email发送本页 在Facebook上分享


Disclaimer Privacy Policy About us Site Map

If you have any requirements, please contact webmaster。(如果有什么要求,请联系站长)
Copyright ©2011-
uuhomepage.com, Inc. All rights reserved.