科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件ASP.NET2.0服务器控件之类型化样式属性

ASP.NET2.0服务器控件之类型化样式属性

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

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

作者:金属边缘 来源:天极开发 2007年11月6日

关键字: Windows

  • 评论
  • 分享微博
  • 分享邮件
下面列举了实现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技术,实现控件客户端功能的内容。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章