VB和VB中的用户界面控件

VB6和VB2005中的用户界面控件
作者:Bill Sempf 来源:msdn

VB6VB2005 中的用户界面控件。本文将向大家介绍如何轻松高效地将 Visual Basic 6 用户界面控件转换到 Visual Basic 2005 中。
简介
在进行 Visual Basic 6 应用程序转换时,有少量控件会比不进行转换的控件带来更多问题。在您拥有源代码的项目的控件、1997 年买回来的自定义 ActiveX 控件以及没有实际转换路径的内置 Microsoft 控件之间,要进行转换不是那么容易的。
不过,还是有可能的。Visual Basic 6 用户控件中的代码可以很好地转换到 Visual Basic 2005 中。您可以通过互操作功能来使用某些第三方控件。Visual Studio 2005 中提供的工具有助于创建 OCX 代理。所有功能都不会丢失。
集成用户控件
最大的问题是 Microsoft 稍微调整了用户控件的定义。由于继承的使用,我们实际上可以将用户控件定义为控件集合,从而扩展控件的概念。在 Visual Basic 6 中,用户控件只是可以驻留在其他窗体中的窗体。
幸运的是 Visual Basic 2005 可以出色地完成更改工作。多数更改工作均在后台进行,但是即使细微的设置,Visual Basic 6 升级向导也能很好地对其进行转换。接下来我将对此进行解释。
将带有用户控件的 Visual Basic 6 项目转移到 Visual Basic 2005 中
我在 Visual Basic 6 中构建了一个小型用户控件(仅实现了用于输入美国社会安全号码的三个文本框)。我将使用一些技巧,进行一些设置以查看转换向导的工作方式。


图 1:Visual Basic 6 SSN 控件
我将使用 TextChanged 事件,以在文本框具有正确的字符数时在它们之间自动切换。我将该事件驻留在一个简单的窗体中(该窗体只是在消息框中显示结果),并通过转换向导运行该事件。这是一个相当简单的过程:只需在 Visual Studio 2005 中使用“文件”->“打开项目...”菜单项来打开 Visual Basic 6 项目。
令人高兴的是 Visual Basic 2005 可以非常出色地对其进行处理。向导可以正确地以 Visual Basic 2005 格式创建窗体和用户控件。甚至还添加了 ToolTip ExtenderProvider,以支持默认情况下 Visual Basic 6 中的 TextBox 控件和用户控件的实例所具有的 ToolTip 属性。(请注意示例程序文件中的程序员注释使用的是英文,本文中将其译为中文是为了便于参考。)
列表 1:两个版本的代码比较
Visual Basic 6 代码


以下是引用片段:
Private Sub Three_Change()
If Len(Three.Text) = 3 Then
Two.SetFocus
End If
End Sub

Private Sub Two_Change()
If Len(Two.Text) = 2 Then
Four.SetFocus
End If
End Sub

Public Property Get SocialSecurityNumber()
SocialSecurityNumber = Three.Text & _
"-" & Two.Text & "-" & Four.Text
End Property

vb。net开发中使用excel插件代码

vb.net开发中使用excel插件代码

  用VB.NET做excel插件开发,可能需要为excel添加自定义的工具栏。这个也是非常的简单的。

以下是引用片段:
   Public Class ConnectClass Connect
   Implements Extensibility.IDTExtensibility2
   Dim app As Excel.Application
   Dim wb As Excel.Workbook
   Dim ws As Excel.Worksheet
   Dim addInInstance As Object
   Dim pasteText As Microsoft.Office.Core.CommandBarButton ‘定义一个工具栏按钮
   Public Sub OnBeginShutdown()Sub OnBeginShutdown(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnBeginShutdown
   End Sub
   Public Sub OnAddInsUpdate()Sub OnAddInsUpdate(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnAddInsUpdate
   End Sub
   Public Sub OnStartupComplete()Sub OnStartupComplete(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnStartupComplete
   End Sub
   Public Sub OnDisconnection()Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array)
   Implements Extensibility.IDTExtensibility2.OnDisconnection
   End Sub
   Public Sub OnConnection()Sub OnConnection(ByVal application As Object, ByVal connectMode As Extensibility.ext_ConnectMode,
   ByVal addInInst As Object, ByRef custom As System.Array)
   Implements Extensibility.IDTExtensibility2.OnConnection
   If TypeOf (application) Is Excel.Application Then app = CType(application, Excel.Application)
   addInInstance = addInInst
   wb = app.ActiveWorkbook
   ws = CType(wb.ActiveSheet, Excel.Worksheet)
   Dim toolbar As Microsoft.Office.Core.CommandBar = Nothing
   If Not app Is Nothing Then
   toolbar = AddToolbar(app, "专用工具栏") ’添加工具栏
   End If
   ’ 建立按钮添加文本
   pasteText = MakeANewButton(toolbar, "Insert text",
   1044, AddressOf pasteText_Click) ’添加工具栏按钮并帮定事件
   End Sub
   ’添加工具栏
   Private Function AddToolbar()Function AddToolbar(ByVal ex As Excel.Application, _
   ByVal toolbarName As String) As Microsoft.Office.Core.CommandBar
   Dim toolBar As Microsoft.Office.Core.CommandBar = Nothing
   Try
   ’ 为add-in建立一个命令条
   toolBar = CType(ex.CommandBars.Add(toolbarName,
   Microsoft.Office.Core.MsoBarPosition.msoBarTop, , True),
   Microsoft.Office.Core.CommandBar)
   toolBar.Visible = True
   Return toolBar
   Catch
   Return Nothing
   End Try
   End Function
   ’在工具栏上添加一个按钮
   Private Function MakeANewButton()Function MakeANewButton(ByVal commandBar As Microsoft.Office.Core.CommandBar, ByVal caption
   As String, ByVal faceID As Integer, ByVal clickHandler As Microsoft.Office.
   Core._CommandBarButtonEvents_ClickEventHandler) As Microsoft.Office.Core.CommandBarButton
   Try
   Dim newButton As Microsoft.Office.Core.CommandBarButton
   newButton = CType(commandBar.Controls.Add(Microsoft.Office.Core.MsoControlType.msoControlButton), Microsoft.Office.Core.CommandBarButton)
   newButton.Caption = caption
   newButton.FaceId = faceID
   AddHandler newButton.Click, clickHandler
   Return newButton
   Catch ex As System.Exception
   Return Nothing
   End Try
   End Function
   ’点击工具条按钮时应该执行的程序
   Public Sub pasteText_Click()Sub pasteText_Click(ByVal barButton As Microsoft.Office.Core.CommandBarButton, ByRef someBool As Boolean)
   Dim text As String = ""
   Dim data As System.Windows.Forms.IDataObject = System.Windows.Forms.Clipboard.GetDataObject()
   If data.GetDataPresent(System.Windows.Forms.DataFormats.Text) Then
   text = data.GetData(System.Windows.Forms.DataFormats.Text).ToString()
   If (Not app Is Nothing) Then
   Me.app.ActiveCell.Value = text
   End If
   End If
   End Sub
   End Class

  这样程序就完成了,赶紧动手体验吧!

NET并不意味着VBNET或C井

.NET并不意味着VB.NET或c#

很有趣,当人们想到.NET 公共语言运行时(CLR)时,它们往往想到VB.NET或c#。但是实际上它们只是支持CLR的大量语言。

很有趣,当人们想到.NET 公共语言运行时(CLR)时,它们往往想到VB.NET或C#。但是实际上它们只是支持CLR的大量语言。Brian Ritchie在他的主页上为我们提供了一个支持CLR的相当全面的语言列表,包括一些老的和一些新的语言。

对于那些还没有放弃“老校语言”如Ada或Cobol和RPG的人,也有支持这些语言的.NET版本,当然也有支持一些新语言的,如perlphppython等。

不断增多的语言是.NET框架容纳能力的一个标志。特别是CLR 正在被大多开发人员社区接纳。虽然有一些开发人员绝不跨过Unix/windows的界限,但是CLR的确为开发人员使用它们选择的语言提供了一种简单方式。

因此,从最初引入CLR五年来,它的一个目标已经实现,因为它为多种不同语言提供了一个公共平台。但是,最终有多少语言会被实际用于商业项目以及开发人员对它们的接受程度,仍是一件令人感兴趣的事情。只有时间会告诉我们答案。

在不装AD的情况下管理SPS的访问群体

在不装AD的情况下管理SPS的访问群体

  第一步、新建本地用户

  在管理->本地用户和组->用户里面添加新用户,譬如叫做newuser,注意要把描述给写好,省得以后忘记这用户属于哪个部门;

  第二步、把本地用户添加到SPS用户列表里面去

  在SPS的网站设置->用户管理里面把这新建的newuser添加进去,选择用户的时候直接打newuser就可以了,注意如果希望把用户添加到访问群体里面,就不能把该用户定义为读者;

  第三步、新建SPS的访问群体

  在网站设置->管理访问群体->创建新群体创建一个群体newgroup出来,设置选用满足任一规则;

  第四步、添加用户群体规则

  在网站设置->管理访问群体->查看访问群体->添加规则里面添加规则,其中操作数选用属性->帐户名,然后运算符选用“=”,注意用户名是带有主机名的,譬如主机名叫做server,那么应该打入server\newuser;

  第五步、登陆SPS完成我的网站创建

  重要啊,这里,要用刚刚建立的用户newuser登陆一次SPS并且要到我的网站那鸟地方爽一下,就是要等系统不知道怎么样搞一下这用户的信息,然后你才能通过搜集把用户添加到刚刚的群体newgroup里面;

  第六步、搜集满足群体规则的用户到访问群体里面

  在网站设置->访问群体设置这鬼地方点击开始搜集 这样终于把newuser这鸟人搞到群体newgroup里面去啦。

  现在打算做一个用户管理的webpart,就是提供一个给用户修改个人密码和管理员管理全体用户信息的地方,这样看起来就可以像Form认证一样。不晓得怎么做,还得继续看SDK...faint...

用VisualC#NET编写服务器日期控件

用Visualc#.NET编写服务器日期控件
来源:aspcool

  Visual c#.net是微软公司出品的一种新的编程语言(以下简称C#),它继承了c语言的一些特性,也加入了一些新的元素。以前用过delphi开发程序的人可能刚开始使用C#的时候,对其有一种似曾相识的感觉(至少包括我)。是的,C#语言的创始人正是以前在Borland公司开发出delphi语言的Anders Hejlsberg。在我开始使用C#开发程序时,就觉得它是一款很棒的开发Windows Form & Web程序的RAD工具。
在开发Web程序方面,C#的出现打破了以前的网页开发模式,实现了与开发Windows

  Form程序一样的所见即所得的功能。C#提供了一些常用的Web Form Control供开发人员使用,并且只需将控件拖入页面中即可,非常简单。但有时这些控件也不能满足开发人员的需要,需要开发人员自己编写用户控件(User Control)或自定义控件(Custom Control)来满足需求。在这里,我将讲解如何在C#中开发服务器控件。

  二、预备知识

  在C#中可以开发两种服务器控件,一个是用户控件(User Control)和自定义控件(Custom Control)。用户控件的本质与页面文件(ASPx文件)差不多,是可被其它aspx页面重复使用的html代码段,当然它也包括后台代码(Code-behind),后缀名是ascx。所以在开发一些公用的静态页面时(例如页头,页脚)经常用到,但它的缺点是不易继承,不易分发,无法编译成二进制代码来进行部署。但是自定义控件的功能就强大许多,它可以被编译成二进制代码(DLL文件),可以被扩展、继承、分发。就像Web Form Control一样,其实它们每个控件就是一个DLL文件。

  开发用户控件比较简单,就像编写一个aspx页面一样,在这里就不介绍了。本文对象是自定义控件。服务器控件的基类是System.Web.UI.Control。如果要开发可视化的服务器控件,那我们需要从System.Web.UI.WebControls来继承,否则从System.Web.UI.Control继承。

  服务器控件在设计时以runat=”server”脚本代码嵌入到aspx文件中来表示此控件是在服务器端运行的。在服务器控件所在页面提交回传(PostBack)过程中是依靠ViewState(视图状态)来维护控件状态的。所以我们在设计服务器控件属性时,其值应保存在ViewState中。
三、代码编写

  C#中有一个日历控件Calendar,但是现在我需要一个可以下拉的日历控件,并且初始时不显示日历,当我点击下拉按钮时才弹出,并且当选择了日期,日历会自动隐藏且选择的日期值会显示到相应的输入框中。显然Calendar控件不能满足我的需要,但是稍后我会在我的自定义控件中用到它。

  首先新建项目,在项目类型中选择Visual C#项目,在模板列表中选择Web控件库,输入项目名称AquaCalendar,然后选择项目所在目录,点击【确定】按钮。C#将会生成基本的框架代码。将项目中的类文件和类名改名为DatePicker(即日期控件的类名)。由于DatePicker是可视化控件,所以我们必须从System.Web.UI.WebControls继承。并且它包括一个输入框,一个按钮和日历控件,需要在DatePicker类中声明它们。像这种以多个服务器控件组合的控件成为复合控件。代码如下,比较重要的方法和代码在注释中会加以说明:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Drawing;

namespace AquaCalendar
{
  [DefaultProperty("Text"), //在属性工具箱中显示的默认属性
  ToolboxData("<{0}:DatePicker runat=server>")]
  public class DatePicker : System.Web.UI.WebControls.WebControl , IPostBackEventHandler
  {
   //选择日期按钮的默认样式
   private const string _BUTTONDEFAULTSTYLE = "BORDER-RIGHT: gray 1px solid; BORDER-TOP: gray 1px solid; BORDER-LEFT: gray 1px solid; CURSOR: hand; BORDER-BOTTOM: gray 1px solid;";

  //按钮默认文本

  private const string _BUTTONDEFAULTTEXT = "...";
   private System.Web.UI.WebControls.Calendar _Calendar;

  public override ControlCollection Controls
   {
    get
    {
     EnsureChildControls(); //确认子控件集都已被创建
     return base.Controls;
    }
   }

  //创建子控件(服务器日历控件)

  protected override void CreateChildControls()
   {
    Controls.Clear();
    _Calendar = new Calendar();
    _Calendar.ID = MyCalendarID;
    _Calendar.SelectedDate = DateTime.Parse(Text);
    _Calendar.TitleFormat = TitleFormat.MonthYear;
    _Calendar.NextPrevFormat = NextPrevFormat.ShortMonth;
    _Calendar.CellSpacing = 0;
    _Calendar.Font.Size = FontUnit.Parse("9pt");
    _Calendar.Font.Name = "Verdana";
    _Calendar.SelectedDayStyle.BackColor = ColorTranslator.Fromhtml("#333399");
    _Calendar.SelectedDayStyle.ForeColor = ColorTranslator.FromHtml("White");
    _Calendar.DayStyle.BackColor = ColorTranslator.FromHtml("#CCCCCC");
    _Calendar.TodayDayStyle.BackColor = ColorTranslator.FromHtml("#999999");
    _Calendar.TodayDayStyle.ForeColor = ColorTranslator.FromHtml("Aqua");
    _Calendar.DayHeaderStyle.Font.Size = FontUnit.Parse("8pt");
    _Calendar.DayHeaderStyle.Font.Bold = true;
    _Calendar.DayHeaderStyle.Height = Unit.Parse("8pt");
    _Calendar.DayHeaderStyle.ForeColor = ColorTranslator.FromHtml("#333333");
    _Calendar.NextPrevStyle.Font.Size = FontUnit.Parse("8pt");
    _Calendar.NextPrevStyle.Font.Bold = true;
    _Calendar.NextPrevStyle.ForeColor = ColorTranslator.FromHtml("White");
    _Calendar.TitleStyle.Font.Size = FontUnit.Parse("12pt");
    _Calendar.TitleStyle.Font.Bold = true;
    _Calendar.TitleStyle.Height = Unit.Parse("12pt");
    _Calendar.TitleStyle.ForeColor = ColorTranslator.FromHtml("White");
    _Calendar.TitleStyle.BackColor = ColorTranslator.FromHtml("#333399");
    _Calendar.OtherMonthDayStyle.ForeColor = ColorTranslator.FromHtml("#999999");
    _Calendar.NextPrevFormat = NextPrevFormat.CustomText;
    _Calendar.NextMonthText = "下月";
    _Calendar.PrevMonthText = "上月";
    _Calendar.Style.Add("display","none"); //默认不显示下拉日历控件
    _Calendar.SelectionChanged += new EventHandler(_Calendar_SelectionChanged);
    this.Controls.Add(_Calendar);
   }
   [
    Category("Appearance"), //该属性所属类别,参见图
    DefaultValue(""), //属性默认值
    Description("设置该日期控件的值。") //属性的描述
   ]

  public string Text
   {
    get
    {
     EnsureChildControls();
     return (ViewState["Text"] == null)?System.DateTime.Today.ToString("yyyy-MM-dd"):ViewState["Text"].ToString();
    }
    set
    {
     EnsureChildControls();
     DateTime dt = System.DateTime.Today;
     try
     {
      dt = DateTime.Parse(value);
     }
     catch
     {
      throw new ArgumentOutOfRangeException("请输入日期型字符串(例如:1981-04-29)!");
     }

    ViewState["Text"] = DateFormat == CalendarEnum.LongDateTime?dt.ToString("yyyy-MM-dd"):dt.ToString("yyyy-M-d");
    }
   }

  //重载服务器控件的Enabled属性,将选择日期按钮变灰(禁用)

  public override bool Enabled
   {
    get
    {
     EnsureChildControls();
     return ViewState["Enabled"] == null?true:(bool)ViewState["Enabled"];
    }
    set
    {
     EnsureChildControls();
     ViewState["Enabled"] = value;
    }
   }

  public string ButtonStyle
   {
    get
    {
     EnsureChildControls();
     object o = ViewState["ButtonSytle"];
     return (o == null)?_BUTTONDEFAULTSTYLE:o.ToString();
    }
    set
    {
     EnsureChildControls();
     ViewState["ButtonSytle"] = value;
    }
   }

  [
    DefaultValue(CalendarEnum.LongDateTime),
   ]

  public CalendarEnum DateFormat
   {
    get
    {
     EnsureChildControls();
     object format = ViewState["DateFormat"];
     return format == null?CalendarEnum.LongDateTime:(CalendarEnum)format;
    }
    set
    {
     EnsureChildControls();
     ViewState["DateFormat"] = value;
     DateTime dt = DateTime.Parse(Text);
     Text=DateFormat == CalendarEnum.LongDateTime?dt.ToString("yyyy-MM-dd"):dt.ToString("yyyy-M-d");
    }
   }

  [
    Browsable(false),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
   ]

  public string MyCalendarID //复合控件ID
   {
    get
    {
     EnsureChildControls();
     return this.ClientID+"_MyCalendar";
    }
   }

  [
    Browsable(false),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
   ]

  public string MyCalendarName //复合控件名称
   {
    get
    {
     EnsureChildControls();
     return this.UniqueID+":MyCalendar";
    }
   }

  [
    Browsable(false),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
   ]

  public string DatePickerInputID //复合控件中输入框的ID
   {
    get
    {
     EnsureChildControls();
     return this.ClientID+"_DateInput";
    }
   }

  [
    Browsable(false),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
   ]

  public string DatePickerInputName //复合控件中输入框的名称
   {
    get
    {
     EnsureChildControls();
     return this.UniqueID+":DateInput";
    }
   }

  [
    Browsable(false),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
   ]

  public string DatePickerButtonID //复合控件中按钮的ID
   {
    get
    {
     EnsureChildControls();
     return this.ClientID+"_DateButton";
    }
   }

  [
    Browsable(false),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
   ]

  public string DatePickerButtonName //复合控件中按钮的名称
   {
    get
    {
     EnsureChildControls();
     return this.UniqueID+":DateButton";
    }
   }

  public string ButtonText
   {
    get
    {
     EnsureChildControls();
     return ViewState["ButtonText"] == null?_BUTTONDEFAULTTEXT:(string)ViewState["ButtonText"];
    }
    set
    {
     EnsureChildControls();
     ViewState["ButtonText"] = value;
    }
   }

  ///
   /// 将此控件呈现给指定的输出参数。
   ///
   /// 要写出到的 HTML 编写器

  protected override void Render(HtmlTextWriter output)
   {
    //在页面中输出控件时,产生一个表格(二行二列),以下是表格的样式
    output.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");
    output.AddAttribute(HtmlTextWriterAttribute.Border, "0");
    output.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");

   output.AddStyleAttribute("LEFT", this.Style["LEFT"]);
    output.AddStyleAttribute("TOP", this.Style["TOP"]);
    output.AddStyleAttribute("POSITION", "absolute");

   if (Width != Unit.Empty)
    {
     output.AddStyleAttribute(HtmlTextWriterStyle.Width, Width.ToString());
    }
    else
    {
     output.AddStyleAttribute(HtmlTextWriterStyle.Width, "200px");
    }

   output.RenderBeginTag(HtmlTextWriterTag.Table); //输出表格
    output.RenderBeginTag(HtmlTextWriterTag.Tr); //表格第一行
    output.AddAttribute(HtmlTextWriterAttribute.Width, "90%");
    output.RenderBeginTag(HtmlTextWriterTag.Td);

   //以下是第一行第一列中文本框的属性及其样式设置

   if (!Enabled)
    {
     output.AddAttribute(HtmlTextWriterAttribute.ReadOnly, "true");
    }

   output.AddAttribute(HtmlTextWriterAttribute.Type, "Text");
    output.AddAttribute(HtmlTextWriterAttribute.Id, DatePickerInputID);
    output.AddAttribute(HtmlTextWriterAttribute.Name, DatePickerInputName);
    output.AddAttribute(HtmlTextWriterAttribute.Value, Text);
    output.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
    output.AddStyleAttribute(HtmlTextWriterStyle.Height, "100%");
    output.AddStyleAttribute(HtmlTextWriterStyle.FontFamily, Font.Name);
    output.AddStyleAttribute(HtmlTextWriterStyle.FontSize, Font.Size.ToString());
    output.AddStyleAttribute(HtmlTextWriterStyle.FontWeight, Font.Bold?"bold":"");
    output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(BackColor));
    output.AddStyleAttribute(HtmlTextWriterStyle.Color, ColorTranslator.ToHtml(ForeColor));
    output.RenderBeginTag(HtmlTextWriterTag.Input); //输出文本框
    output.RenderEndTag();
    output.RenderEndTag();
    output.AddAttribute(HtmlTextWriterAttribute.Width, "*");
    output.RenderBeginTag(HtmlTextWriterTag.Td);

   //以下是第一行第二列中按钮的属性及其样式设置

   if (!Enabled)
    {
     output.AddAttribute(HtmlTextWriterAttribute.Disabled, "true");
    }

   output.AddAttribute(HtmlTextWriterAttribute.Type, "Submit");
    output.AddAttribute(HtmlTextWriterAttribute.Id, DatePickerButtonID);
    output.AddAttribute(HtmlTextWriterAttribute.Name, DatePickerButtonName);
    output.AddAttribute(HtmlTextWriterAttribute.Value, ButtonText);
    output.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
    output.AddAttribute(HtmlTextWriterAttribute.Onclick, Page.GetPostBackEventReference(this)); //点击按钮时需要回传服务器来触发后面的OnClick事件

   output.AddAttribute(HtmlTextWriterAttribute.Style, ButtonStyle);
    output.RenderBeginTag(HtmlTextWriterTag.Input); //输出按钮
    output.RenderEndTag();
    output.RenderEndTag();

   output.RenderEndTag();
    output.RenderBeginTag(HtmlTextWriterTag.Tr);
    output.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
    output.RenderBeginTag(HtmlTextWriterTag.Td);
    _Calendar.RenderControl(output); //将日历子控件输出
    output.RenderEndTag();
    output.RenderEndTag();
    output.RenderEndTag();
   }

  //复合控件必须继承IpostBackEventHandler接口,才能继承RaisePostBackEvent事件

  public void RaisePostBackEvent(string eventArgument)
   {
    OnClick(EventArgs.Empty);
   }

  protected virtual void OnClick(EventArgs e)
   {
    //点击选择日期按钮时,如果日历子控件没有显示则显示出来并将文本框的值赋值给日历子控件
    if (_Calendar.Attributes["display"] != "")
    {
     _Calendar.SelectedDate = DateTime.Parse(Text);
     _Calendar.Style.Add("display","");
    }
   }

  //复合控件中的日历控件日期变化事件

  private void _Calendar_SelectionChanged(object sender, EventArgs e)
   {
    //当选择的日期变化时,将所选日期赋值给文本框并将日历子控件隐藏
    Text = _Calendar.SelectedDate.ToString();
    _Calendar.Style.Add("display","none");
   }
  }
}

  在上面的代码中,需要注意以下几点:

  ·如果你想将此控件的某些属性供重载,则在声明属性前加上virtual关键字;

  ·在页面输出此控件时(即在Render事件中),是先定义子控件的样式或属性,然后再产生子控件;

  ·在隐藏日历子控件时,建议不要使用Visible属性来显示/隐藏,使用Visible=false隐藏时服务器端将不会将日历控件HTML代码发送给客户端,会导致复合控件装载日历控件的表格会空白一块出来,影响页面的布局。所以使用样式display=none设置来使日历控件在客户端隐藏,但是HTML代码依然存在于页面中;

  <p>  四、结束语 </p>
  <p><span>  在编写服务器控件时,需要一定的HTML语言基础,也要清楚.NET程序的请求处理方式。服务器控件封装了客户端行为及逻辑判断,无需开发者添加更多代码。当然,有些地方使用服务器控件可以带来方便,但是也增加了服务器的负荷。有时适当的结合javascript使一些代码在客户端运行,可提高WEB应用程序效率</span></td>