资源描述
用Visual C#.NET编写服务器日期控件一、序言
Visual C#.nel是微软公司出品的一种新的编程语言(以下简称C#),它继承了 C 语言的一些特性,也加入了一些新的元素。以前用过Delphi开发程序的人可能刚开始 使用C#的时候,对其有•种似曾相识的感觉(至少包括我)。是的,C#语言的创始人正 是以前在Borland公司开发出Delphi语言的Anders Hejlsbergo在我开始使用C#开发 程序时,就觉得它是一款很棒的开发Windows Form & Web程序的RAD工具。
在开发Web程序方面,C#的出现打破了以前的网页开发模式,实现了与开发Windows
Form程序一样的所见即所得的功能。C#提供了一些常用的Web Form Control供开 发人员使用,并且只需将控件拖入页面中即可,非常简单。但有时这些控件也不能满足 开发人员的需要,需要开发人员自己编写用户控件(User Control)或自定义控件(Custom Control)来满足需求。在这里,我将讲解如何在C#中开发服务器控件。
二、预备知识
在C#中可以开发两种服务器控件,一个是用户控件(UserControl)和自定义控件 (Custom Control) o用户控件的本质与页面文件(ASPx文件)差不多,是可被其它 aspx页面重复使用的HTML代码段,当然它也包括后台代码(Code-behind),后缀名是 asexo所以在开发一些公用的静态页面时(例如页头,页脚)经常用到,但它的缺点是 不易继承,不易分发,无法编译成二进制代码来进行部署。但是白定义控件的功能就强 大许多,它可以被编译成二进制代码(DLL文件),可以被扩展、继承、分发。就像Web Form Control 一样,其实它们每个控件就是一个DLL文件。
开发用户控件比拟简单,就像编写一个aspx页面一样,在这里就不介绍了。本文 对象是自定义控件。服务器控件的基类是System. Web. UI. Control。如果要开发可视化 的服务器控件,那我们需要从System. Web. UI. WebControls来继承,否那么从 System. Web. UI. Control 继承。
output. AddAttribute(HtmlTextWriterAttribute. Name, DatePickerButtonName);output. AddAttributc(HtmlTcxtWri tcrAttributc. Value, ButtonTcxt):
output. .AddStyleAttributeCHtmlTextWriterStyle. Width, "100$");output. AddAttributedltmlTextWri terAttribute. Oncl ick,
Page. GetPostBackEventReference(this)): 〃点击按钮时需要回传服务器来触发后面的 OnClick 事件output. .i\dd/\ttribute(HtmlTextWriterAttribute. Style, ButtonStyle):
output. RenderBcginTag(HtmlTextWriterTag. Input); //输出按钮output. RenderEndTagO ;
output. RenderEndTagO ;output. RenderEndTagO ;
output. RenderBeginTag(HtmlTextWriterTag. Tr);output. AddAttributeOltmlTextWri terAttribute. Col span, "2");
output. RenderBeginTag(HtmlTextWriterTag. Td);Calendar. RenderControl (output); 〃将日历子控件输出
output. RenderEndTagO ;output. RenderEndTagO ;
output. RenderEndTagO ; )
〃复合控件必须继承IpostBackEventHandler接口,才能继承RaisePostBackEvent事件public void RaisePostBackEvent(string cvcntArgumcnt) (
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 = _Calcndar. SclcctedDatc. ToStringO ;_Calendar. Style. Add("display","none");
)
} }
在上面的代码中,需要注意以下几点:
• 如果你想将此控件的某些属性供重载,那么在声明属性前加上virtual关键字;
• 在页面输出此控件时(即在Render事件中),是先定义子控件的样式或属性, 然后再产生子控件;
• 在隐藏日历子控件时,建议不要使用Visible属性来显示/隐藏,使用 Visible=false隐藏时服务器端将不会将口历控件HTML代码发送给客户端,会导致复合 控件装载日历控件的表格会空白一块出来,影响页面的布局。所以使用样式 display:none设置来使日历控件在客户端隐藏,但是HTML代码依然存在于页面中;
B CK)
48Px
Mh
136PM
□注第
(DdtaBndir^)
□
外,
BdckCotor BxderCdcr Bordet **
Border MMth
ftXtorGtyte
BORD€R RIGHT: gray IpM soM; B
ButtonText
Ma
D^eFcrm^
lonjpMeTwne
Q Ry*
ForeCdor
□
Text
200S-12-01
日行为
AccessKey
EnaUed
True
En4deV5ev6tate
True
Tabindex
0
ToolTp
VHit4e
True
日奈厚
DatrPKkrrl
偿性。三
DatePKketl AQjdCatenda MtePHw
瓦%回刃H
Text
设置该日m按丽b・
3 WrbForml - Microsoft Internet Explorer
文件© 物睚)S9W 4URCA) XJKD 帮助(mf J
8后退・• • © @ GI ◎披案力收♦夹
地址(Q),Imcdhost/TestWob/TosKontrd.ospx T ~转到 播接“
[2005-12-2
2005年 12月
星明日星期一星期二星u三星m四
星期五星期六
9成及致 叁152222 zll212a
叁心阳2Z 5121281 4111825
福完毕
就本地intranet
K*决方寞资>»?告整器野屋性
四、结束语
在编写服务器控件时,需要一定的HTML语言基础,也要清楚.NET程序的请求处理 方式。服务器控件封装了客户端行为及逻辑判断,无需开发者添加更多代码。当然,有 些地方使用服务器控件可以带来方便,但是也增加了服务器的负荷。有时适当的结合JavaScript使一些代码在客户端运行,可提高WEB应用程序效率。 附录资料:
不需要的可以自行删除Abstract: Based on the comprehensive analysis on the plastic part's structure service requirement, mounding quality and mould menu factoring cost. A corresponding injection mould of internal side core pulling was designed. By adopting the multi-direction and multi-combination core-pulling. A corresponding injection mould of internal side core pulling was designed, the working process of the mould was introduced
C语言详解-枚举类型注:以下全部代码的执行环境为VC++6.0 在程序中,可能需要为某些整数定义一个别名,我们可以利用预处理指令#define来完成这 项工作,您的代码可能是:
#define MON Idcfine TUE 2
# define WED 3define THU 4
# define FRI 5define SAT 6
# dcfinc SUN 7在此,我们定义一种新的数据类型,希望它能完成同样的工作。这种新的数据类型叫枚举型。
1 .定义一种新的数据类型-枚举型
以下代码定义了这种新的数据类型-枚举型cnum DAY
{
MON=1,TUE, WED, THU, FRI, SAT, SUN};
(1)枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号, 隔开。
⑵DAY是一个标识符,可以看成这个集合的名字,是一个可选项,即是可有可无的项。
(3)第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加I。
(4)可以人为设定枚举成员的值,从而自定义某个范围内的整数。
(5)枚举型是预处理指令#define的替代。
(6)类型定义以分号;结束。
2 .使用枚举类型对变量进行声明新的数据类型定义完成后,它就可以使用了。我们已经见过最基本的数据类型,如:整型ini, 单精度浮点型float,双精度浮点型double,字符型char,短整型short等等。用这些基本数据 类型声明变量通常是这样:
char char int
a; 〃变量a的类型均为字符型char letter;y,
z; 〃变量x,y和z的类型均为整型int int number;double m, n;
double result; 〃变显result的类型为双精度浮点型double 既然枚举也是一种数据类型,那么它和基本数据类型一样也可以对变量进行声明。
方法一:枚举类型的定义和变量的声明分开enuni DAY {
MON=1,TUE, WED, THU, FRI, SAT, SUN1;
enuni DAY yesterday;enum DAY today;
enum DAY tomorrow; 〃变a tomorrow 的类型为枚举型 enum DAYenum DAY good_day, bad_day; //变量 good_day 和 bad_day 的类型均为枚举型 enum DAY 方法二:类型定义与变量声明同时进行:
enum〃跟第一个定义不同的是,此处的标号DAY省略,这是允许的。 {Saturday, sunday = 0, monday, tuesday, Wednesday, thursday, friday
} workday; 〃变量workday的类型为枚举型enum DAYenuni week { Mon=l, Tue, Wed, Thu, Fri Sat, Sun} days; 〃变量 days 的类型为枚举型 enum week
enum BOOLEAN { false, true } end_flag, match_flag; 〃定义枚举类型并声明了两个枚举型变 量方法三:用typedef关键字将枚举类型定义成别名,并利用该别名进行变量声明: typedef enum workday (
Saturday, sunday = 0, monday, tuesday, Wednesday, thursday, friday} workday; 〃此处的workday为枚举型enum workday的别名
workday today, tomorrow; 〃变量 today 和 tomorrow 的类型为枚举型 workday,也即 enum workday enum workday 中的 workday 可以省略:
(ypedef enum {Saturday, sunday = 0, monday, tuesday, Wednesday, ihursday, friday
} workday; 〃此处的workday为枚举型enum workday的别名workday today, tomorrow; 〃变量 loday 和 tomorrow 的类型为枚举型 workday,也即 enum workday
也可以用这种方式:
typedef enum workday {
Saturday, sunday = 0, monday, tuesday, Wednesday, thursday, friday );workday today, tomorrow; 〃变量 today 和 tomorrow 的类型为枚举型 workday,也即 enum workday
注意:同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的命名常 量。错误例如如下所示:
错误声明•:存在同名的枚举类型typedef enum {
Wednesday, thursday, friday } workday;typedef enum WEEK
Saturday, sunday = 0, monday, } workday;错误声明二:存在同名的枚举成员
typcdcf cnum (
Wednesday,
thursday, friday } workday」;typcdcf enum WEEK {
Wednesday, sunday = 0, monday, } workday_2;.使用枚举类型的变量
2.1 对枚举型的变量赋值。
实例将枚举类型的赋值与基本数据类型的赋值进行了比照:
方法一:先声明变量,再对变量赋值#include<stdio.h>
/*定义枚举类型*/enum DAY { MON=kTUE, WED, THU. FRI. SAT, SUN };
void main() {
/*使用基本数据类型声明变量,然后对变量赋值*/ int x, y, z;
x= 10;
y = 20; z = 30;
/*使用枚举类型声明变量,再对枚举型变量赋值*/ cnum DAY yesterday, today, tomorrow;
yesterday = MON;
today = TUE;
tomorrow = WED:
printf("%d %d %d \n", yesterday, today, tomorrow);方法二:声明变量的同时赋初值
/include <stdio.h>/*定义枚举类型*/
enum DAY { MON=1,TUE, WED, THU. FRI, SAT, SUN };void niain()
{
/*使用基本数据类型声明变量同时对变量赋初值*/ int x=10, y=20, z=30;
/*使用枚举类型声明变量同时对枚举型变量赋初值*/ enum DAY yesterday = MON,
today = TUE, tomorrow = WED;
printf("%d %d %d \n", yesterday, today, tomorrow);I
方法三:定义类型的同时声明变量,然后对变量赋值。
#include <stdio.h>/*定义枚举类型,同时声明该类型的三个变量,它们都为全局变量*/
enum DAY { MON=1, TUE, WED, THU. FRI, SAT, SUN } yesterday, today, tomorrow;产定义三个具有基本数据类型的变量,它们都为全局变量*/ int x, y, z;
void main()
/*对基本数据类型的变量赋值*/
x = 10; y = 20; z = 30;
/*对枚举型的变量赋值*/
yesterday = MON;
today = TUE;
tomorrow = WED;
printf("%d %d %d \n", x, y, z); 〃输出:10 20 30
printf("%d %d %d \n", yesterday, today, tomorrow); 〃输出:12 3)
方法四:类型定义,变量声明,赋初值同时进行。
#include <stdio.h>/*定义枚举类型,同时声明该类型的三个变量,并赋初值。它们都为全局变量*/ enum DAY
{
MON=1,
TUE,
WED.
THU,
FRI,
SAT,
SUN}
yesterday = MON, today = TUE, tomorrow = WED;/*定义三个具有基本数据类型的变量,并赋初值。它们都为全局变量*/
inlx= 10,y = 2O,z = 3O;void main()
{
printf("%d %d %d \n", x, y, z); 〃输出:10 20 30
printf("%d %d %d \n", yesterday, today, tomorrow); 〃输出:12 31
2.2 对枚举型的变量赋整数值时,需要进行类型转换。
#include <stdio.h>enum DAY { MON=1,TUE, WED, THU, FRI, SAT, SUN };
void main()
enum DAY yesterday, today, tomorrow;
yesterday = TUE;
today = (enum DAY) (yesterday + 1); 〃类型转换
tomorrow = (enuni DAY) 30; 〃类型转换
//tomorrow = 3; 〃错误
printf("%d %d %d \n", yesterday, today, tomorrow); 〃输出:2 3 30 )使用枚举型变量
#include<stdio.h>enum
{
BELL='\a;
BACKSPACE = '\b',
HTAB=W
RETURN=V,
NEWLINE= \n\
VTAB= W,
SPACE= *'I;
enum BOOLEAN { FALSE = 0, TRUE } match_flag;void main()
{
int index = 0;
int count_oUetter = 0;
int count_ofLspace = 0;
char str[] = "I'm Ely efod";
match_flag = FALSE;
for(; str[index] != *\0'; index++)if( SPACE != str[index])
count_of_lctter++;else
{match_nag = (enum BOOLEAN) 1;
count_oLspace++;
服务器控件在设计时以runal二" 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></{0}:DatePicker>*)]
public class DatePicker : System. Web. UI. WebControls. WebControl ,
IPostBackEventHandler printf("%s %d times %c", match_flag ? "match": "not match", count_of_space, NEWLINE); printf("coiint of letters: %d %c%c", count_of_letter. NEWLINE. RETURN);} 输出: match 2 times count of letters: 10 Press any key to continue
3 .枚举类型与sizeof运算符#include <stdio.h>
enum escapes {
BELL = '\a',
BACKSPACE = '\b',
HTAB= '\t',
RETURN= V,
NEWLINE= '\n;
VTAB= W,
SPACE='*I;
enum BOOLEAN { FALSE = 0, TRUE } match_flag;void main() {
printf("%d bytes \n", sizcof(cnum escapes)); //4 bytes
printf("%d bytes \n", sizeof(escapes)); //4 bytes
prinlf("%d bytes \n*\ sizeof(enum BOOLEAN)); //4 bytes
printf("%d bytes \n", sizeof(BOOLEAN)); //4 bytes
printf("%d bytes \n", sizeof(match_flag)); //4 bytes
printf("%d bytes \n", sizcof(SPACE)); //4 bytes
printf("%d bytes \n", sizeof(NEWLINE)); //4 bytes
printf("%d bytes \n", sizeof(FALSE)); //4 bytes
printf("%d bytes \n*\ sizeof(0)); //4 bytes I 5.综合举例 #include<stdio.h> enum Season
spring. summer= 100, fall=96. winter typcdcf cnum(
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday)
Weekday;void main()
{
/* Season */
printf("%d \n", spring); // 0
printf("%d, %c \nH, summer, summer); // I (X), d
printf("%d \n", fall+winter); // 193
Season mySeason=winter;
if(wi ntcr==myScason)printf("mySeason is winter \n"); // mySeason is winter
int x=100;
if(x==summer)prinlf("x is equal to summer\n"); // x is equal to summer
printf("%d bytes\n", sizcof(spring)); // 4 bytes
/* Weekday */
printfC^izeof Weekday is: %d \n", sizeof(Weekday)); //sizeof Weekday is: 4
Weekday today = Saturday;
Weekday tomorrow;if( today == Monday) tomorrow = Tuesday;
else
tomorrow = (Weekday) (today + I); //remember to convert from int to Weekday }本文来自CSDN--xiaobai32966博客
〃选择日期按钮的默认样式
private const string _BUTTONDEFAULTSTYLE = "BORDER-RIGHT: gray Ipx solid;BORDER-TOP: gray Ipx solid; BORDER-LEFT: gray Ipx solid; CURSOR: hand; BORDER-BOTTOM: gray Ipx solid;";
〃按钮默认文本private const string BLTTONDEFAULTTEXT =
private System. Web. UI. WcbControls. Calendar .Calendar;public override ControlCollection Controls ( get (
EnsureChildControlsO ; //确认子控件集都已被创立 return base. Controls;
) )
〃创立子控件(服务器日历控件)protected override void CreateChiIdControlsO (
Controls. Clear ();.Calendar = new Calendar();
_Calendar. ID = MyCalendarlD;_Calendar. SelectedDale = DaleTime. 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. FromHtnil ("#333399");
Calendar. SelectedDayStyle. ForeColor = ColorTranslator. FromHtml("White");—Calendar. DayStyle. BackColor - ColorTranslator. FromHtml("#CCCCCC");
Calendar. TodayDayStyle. BackColor = ColorTranslator. FromHtml(*#999999*);—Calendar. TodayDayStyle. ForcColor = ColorTranslator. FromHtml (*Aqua,z);
Calendar. DayHeaderStyle. Font. Size = FontUnit. Parse(w8ptw);_Calendar. DayHeaderStyle. Font. Bold = true:
_Calendar. DayHeaderStyle.Height = Unit. Parse(*8pt*);.Calendar. DayHeaderStyle. ForeColor = ColorTranslator. FromHlml("#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");
_Calcndar. TitlcStylc. Font. Bold = true;_Calendar.TitleStyle. Height = Unit. Parse(*12pt*);
Calendar. TitleStyle. ForeColor = ColorTranslator. FromHtml(*White*);_Calendar. TitleStyle. BackColor = ColorTranslator. EromUtml("#333399");
Calendar. 01herMonthDaySty1e. ForeCo1or = ColorTranslator. FromHtml("#999999");_Calendar. NextPrevFormat = NextPrevFormat. CustomText:
Calendar. NextMonthText ="下月";
.Calendar. PrevMonthText ="上月";
.Calendar. Style. Add("display", "none"); 〃默认不显示下拉口历控件
.Calendar. SeieelionChanged += new EventHand1 er(_Ca1endar_Se1ectionChanged);
this. Controls. Add(.Calendar): ) [
Category (^Appearance"), 〃该属性所属类别,参见图
DefaultValue 〃屈性默认值
Description("设置该日期控件的值,〃属性的描述
]
public string Text (get
( EnsureChildControlsO : return (VicwStatcE'Text"]==
null)?System. Dat eTime. Today. ToStringt^yyyy-MM-dd*): ViewS tatet^ext^]. ToStringO :
} set (EnsureChildControlsO ;
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-VM-dd"):dt. ToString("yyyy-M-d");
)〃重载服务器控件的Enabled属性,将选择口期按钮变灰(禁用)
public override bool Enabled ( get (
EnsurcChildControlsO ;
return ViewState[*Enabled*] == null?true:(bool)ViewState["Enabled"]; } set (
EnsureChildControlsO ;
ViewState["Enabled”〕 = value; }
)public string ButtonStyle (
get (
EnsureChildControlsO ;
object o = ViewState[*ButtonSytle/,];
return (o == null)?_BUTTONDEFAULTSTYLE:o. ToStringO ; } set (
EnsureCh i1dControls();
ViewState[*ButtonSytle*] = value; ) )
[
DefaultValue(CalendarEnum. LongDateTime), ]public CalendarEnum DateFormat ( get
EnsureCh i1dControls();object format = ViewState[*DateFormatw];
return format =- null?CalendarEnum. LongDateTime:(CalendarEnum)format;) set (
EnsureChi IdControlsO ;ViewState[*DateFormatw] = value;
DateTime dt = DateTime. Parse(Text);Text=DateFormat ==
CalendarEnum. LongDateTime?dt. ToString(z,yyyy-MM-(ldw) :dt. ToStringCyyyy-M-dw);)
)
[
Browsab1e(fa1se),
DesignerSerializationVisibility(DesignerSerializationVisibility. Hi
展开阅读全文