Discuz!NT在开源之后,还没什么文章来说明 Discuz!NT项目的一些特点。作为这个控件库的设
计者,本人将在接下来的时间里用连载的方式来向大家解释其中一些控件的设计思想,实现功能以及
一些未曾使用过的功能展示(因为管理后台只使用控件的部分功能)。同时因为这组控件开发的周期
很短(当时仅用一个半月,后不断增强功能),有不少思路和控件设计的规范相驳,但当时只考虑为
后台程序开发和订制方便,因此就暂且开发成了这个样子,但本人日后会不断完善和规范这些代码:)
在开源之后,还没什么文章来说明 Discuz!NT项目的一些特点。作为这个控件库的设计者,本人
将在接下来的时间里用连载的方式来向大家解释其中一些控件的设计思想,实现功能以及一些未曾
使用过的功能展示(因为管理后台只使用控件的部分功能)。同时因为这组控件开发的周期很短(当
时仅用一个半月,后不断增强功能),有不少思路和控件设计的规范相驳,但当时只考虑为后台程序
开发和订制方便,因此就暂且开发成了这个样子,但本人日后会不断完善和规范这些代码:)
为了便于大家下载和使用这组控件,本人在源代码的基本上去掉了与项目相关的一些令人费解的
的代码。同时把相关的控件与具体运行实例相绑定,这只是为了让大家使用和分析方便,必定不是库
中所有控件大家都愿意用或感兴趣。正所谓投其所好嘛。另外下载包中的文件所在的项目和文件位置
也是与开源项目中的配置相一致的,这么搞可以方便大家按图索骥,以便于同步开源项目中的文件。
同时,本人也希望园子里同行在使用和测试这组代码时将您的意见或建议提出来,以便改进和优
化代码。还有就是这些控件代码是能在.net1.0 .net2.0框架上运行。欢迎大家使用:)
好了,今天就先说一下 Button 控件。
先贴一张运行效果图让大家看一下:
![](https://www.cnblogs.com/images/cnblogs_com/daizhj/runpic.JPG)
开发动机:在去年10月底时,后台UI进行了一次重构,因为对.net 中的button控件和图片按钮
控件感到控制不灵活(项目需要一个既有text 属性,又有img字段属性的按钮)。在看到了CS项目中
所使用的按钮后,决定尝试实现与其类似的功能设计。另外因为当时设计部无法对我们直接进行支持,
所以决定样式(css)直接采用cs中所使用的样式(偷个赖)。
实现功能:希望提供两种或以上的按钮样式,同时支持JS脚本注册,以及在客户端表单验证等。
因为要求做出多个显示样式,所以使用枚举方式显示可能选择的样式类型,相关代码如下:
1![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
properytyButtontypeMode 按钮样式#region properytyButtontypeMode 按钮样式
2
public enum ButtonType
3![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
4
Normal, //普通
5
WithImage, //带图
6
XpStyle //不带图
7
}
8![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
public ButtonType ButtontypeMode
11![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
12
get
13![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
14
object obj = ViewState["ButtontypeMode"];
15
return obj == null ? ButtonType.WithImage : (ButtonType)obj;
16
}
17
set
18![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
19
ViewState["ButtontypeMode"] = value;
20
}
21
}
22
#endregion
23![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
24![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
而脚本注册属性为string ,用于输入和保存相关脚本信息
1
[Description("图版按钮链接"), DefaultValue("../images/")]
2
public string ScriptContent
3![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
4
get
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
6
object obj = ViewState["ScriptContent"];
7
return obj == null ? "" : (string)obj;
8
}
9
set
10![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
11
ViewState["ScriptContent"] = value;
12
}
13
}
14![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
是否支持客户端表单验证的属性如下:
1![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
定义是否调用js函数validate(this.form);进行数据校验#region 定义是否调用js函数validate(this.form);进行数据校验
2
private bool _validateForm = false;
3
//定义是否调用js函数validate(this.form);进行数据校验
4
public bool ValidateForm
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
6
set
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
8
this._validateForm = value;
9
}
10
get
11![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
12
return this._validateForm;
13
}
14
}
15
#endregion
16![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
有了这几个属性,就可以在控件的Render函数中使用相关的设置了
1
protected override void Render(HtmlTextWriter output)
2![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
3
//如果应用系统样式,这里只为当没有CSS文件时,则直接将样式写到控件中
4
if (ApplyDefaultStyle)
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
6
if (this.ButtontypeMode == ButtonType.Normal)
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
8
output.Write("<span><a href=\"javascript:void(0);\" style=\"BORDER-RIGHT:
9
#999999 1px solid; PADDING-RIGHT: 10px; BACKGROUND-POSITION: 1px 1px; BORDER-TOP:
10
#cccccc 1px solid; DISPLAY: inline-block; PADDING-LEFT: 10px; FONT-WEIGHT: bold;
11
![](https://www.cnblogs.com/Images/dot.gif)
![](https://www.cnblogs.com/Images/dot.gif)
12
}
13![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
if (this.ButtontypeMode == ButtonType.WithImage)
15![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
16
output.Write("<span><a href=\"javascript:void(0);\" style=\"BORDER-RIGHT: #999999 1px solid;
17
PADDING-RIGHT: 3px; BACKGROUND-POSITION: 1px 1px; BORDER-TOP: #cccccc 1px solid;
18
DISPLAY: inline-block; PADDING-LEFT: 22px; FONT-WEIGHT: bold; FONT-SIZE: 12px;
19
PADDING-BOTTOM: 3px; MARGIN: 1px; BORDER-LEFT: #cccccc 1px solid; CURSOR: pointer;
20
![](https://www.cnblogs.com/Images/dot.gif)
![](https://www.cnblogs.com/Images/dot.gif)
21
}
22![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
if (this.ButtontypeMode == ButtonType.XpStyle)
24![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
25
output.Write("<span style=\"BACKGROUND-POSITION: left top; DISPLAY: inline-block;
26
display: -moz-inline-box; PADDING-LEFT: 4px; FONT-WEIGHT: bold; FONT-SIZE: 12px;
27
BACKGROUND-IMAGE: url(" + this.XpBGImgFilePath + "/xpbuttonbg_l.gif);
28
![](https://www.cnblogs.com/Images/dot.gif)
![](https://www.cnblogs.com/Images/dot.gif)
29
}
30
}
31
![](https://www.cnblogs.com/Images/dot.gif)
![](https://www.cnblogs.com/Images/dot.gif)
![](https://www.cnblogs.com/Images/dot.gif)
32![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
33
//表单验证属性判断,(注:要在web页面上FORM的submit中加入该函数,并进行相关声明
34
//即可,参见webtest页面)
35
if (ValidateForm)
36![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
37
sb.Append("if(validate(this.form)){");
38
//当验证通过后则执行向服务器提交内容的JS代码
39
sb.Append(Page.GetPostBackEventReference(this,"") + ";}");
40
![](https://www.cnblogs.com/Images/dot.gif)
![](https://www.cnblogs.com/Images/dot.gif)
41![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
42
//用户希望进行注册的JS代码,这块代码可放在表单验证属性判断之前。
43
if (ScriptContent != "")
44![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
45
sb.Append(ScriptContent);
46
}
47![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
48
//将上来的设置写入到客户端的onlick事件中。
49
output.WriteAttribute("onclick", sb.ToString());
50
}
51![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
52![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
53![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
54![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
现在可以说从服务器端设置到客户端脚本生成基本上都开发完了。
接下来是做服务器端事件的绑定处理,
1
protected static readonly object EventClick = new object();
2![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
3
public event EventHandler Click
4![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
5
add
6![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
7
Events.AddHandler(EventClick, value);
8
}
9
remove
10![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
11
Events.RemoveHandler(EventClick, value);
12
}
13
}
14![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
15
protected virtual void OnClick(EventArgs e)
16![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
17
EventHandler clickHandler = (EventHandler)Events[EventClick];
18
if (clickHandler != null)
19![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
20
clickHandler(this, e);
21
}
22
}
23![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
24![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
25
public void RaisePostBackEvent(string eventArgument)
26![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
27
OnClick(new EventArgs());
28
}
29![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
30![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
31
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
32![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
33
this.RaisePostBackEvent(eventArgument);
34
}
35![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
36![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
这样就完成了这个控件的主干部分,而其它的一些属性,如图片路径之类的代码大家可参见一下源码,这
里就不多做说明了。
未来实现的功能,应该说主要还是在UI表现上,希望能让用户的接受起来更快,色调也更加柔和等等......
下载链接:/Files/daizhj/ControlsTest.rar