ExtenderControl是AJAX.NET框架里扩展控件的基类,比如ControlToolKit里的一些扩展控件就是从这个基类派生而来。这也是AJAX.NET框架提供给用户在客户端定义Behavior的一种方式。这种客户端的Behavior主要用于扩展服务器控件的行为,让服务器控件有更多的客户端功能,提供更好的用户体验。而这种扩展控件的方式是不改变原有服务器的行为,只是新增功能,也算是一种装饰模式。
这里所做的Extender控件的功能是实现服务器控件在页面上可被拖放,当然这个功能在强大的AJAX.NET的预览版本里已经有了很好的实现,我这里所做的也只是简单的拖放。基本的思路是采用AJAX正式版框架里定义Behavior的方式,然后定义一些模拟拖放的事件。实现拖放的逻辑也很简单,当需要拖放的对象被点击之后,给body添加mousemove和mouseup事件,具体的移动逻辑在mousemove里实现,mouseup则清空body的事件,拖放结束。这个逻辑也是按照<<javascript高级编程>>书上介绍的方法,没有特别深奥的东西。说白了就是演练一下定义extender控件,把一些老的东西重新包装一下。除了简单的拖放逻辑,还提供了一个属性dragCssClass,就是在拖放的时候的样式,比如设置鼠标为move等等。具体代码如下
1.首先定义个extender继承ExtenderControl,当然这个要引用AJAX.NET的System.Web.Extension.dll.要指定
[TargetControlType(typeof(Control))]类型,还需要注册脚本,脚本当然也是嵌入到资源中的。基类方法的作用请看AJAX.NET提供的帮助。
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
DragExtender
1
[assembly: WebResource("AjaxControl.DragBehavior.js", "text/javascript")]
2
namespace AjaxControl
3![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
4
[TargetControlType(typeof(Control))]
5
public class DragExtender : ExtenderControl
6![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
7
private string _dragCssClass;
8![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
9
/// 拖动时的样式
10
/// </summary>
11
public string DragCssClass
12![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
13![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return _dragCssClass; }
14![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ _dragCssClass = value; }
15
}
16![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(Control targetControl)
18![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
19
ScriptBehaviorDescriptor descriptor = new ScriptBehaviorDescriptor("Shenba.DragBehavior", targetControl.ClientID);
20
descriptor.AddProperty("dragCssClass", this._dragCssClass);
21![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
return new ScriptBehaviorDescriptor[]
{ descriptor };
22
}
23![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
24
protected override IEnumerable<ScriptReference> GetScriptReferences()
25![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
26
string jsPath = ResolveClientUrl("AjaxControl.DragBehavior.js");
27
ScriptReference reference = new ScriptReference(jsPath);
28![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
return new ScriptReference[]
{ reference };
29
}
30![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
31
protected override void OnPreRender(EventArgs e)
32![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
33
if (!this.DesignMode)
34![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
35
// 将脚本添加到scriptmanager的脚本引用中
36
ScriptManager sm = ScriptManager.GetCurrent(Page);
37
if (sm == null)
38![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
39
throw new HttpException("a scriptmanager is required in the page.");
40
}
41
sm.Scripts.Add(new ScriptReference("AjaxControl.DragBehavior.js", "AjaxControl"));
42
}
43
base.OnPreRender(e);
44
}
45
}
46
}
47![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2.接下来是js的脚本,也是核心逻辑的一部分
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
DragBehavior.js
1
Type.registerNamespace("Shenba");
2![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
3
Shenba.DragBehavior = function (element)
4![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
5
Shenba.DragBehavior.initializeBase(this, [element]);
6
// 分别用于记录鼠标落点与目标对象坐标的偏差
7
this._diffX = 0;
8
this._diffY = 0;
9
}
10![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
11![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Shenba.DragBehavior.prototype =
{
12
initialize : function ()
13![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
14
Shenba.DragBehavior.callBaseMethod(this, "initialize");
15
16
// 将目标对象的定位转化成绝对定位
17
this.get_element().style.position = "absolute";
18
this._mouseDownHandler = Function.createDelegate(this, this._onMouseDown);
19
$addHandler(this.get_element(), "mousedown", this._mouseDownHandler);
20
},
21
22
set_dragCssClass : function(value)
23![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
24
if (this._dragCssClass !== value)
25![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
26
this._dragCssClass = value;
27
this.raisePropertyChanged("dragCssClass");
28
}
29
},
30
get_dragCssClass : function()
31![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
32
return this._dragCssClass;
33
},
34
35
_onMouseDown : function (e)
36![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
37
var ele = this.get_element();
38
this._diffX = e.clientX - ele.offsetLeft;
39
this._diffY = e.clientY - ele.offsetTop;
40
41
// 给body添加mouseMove合mouseUp事件
42
this._mouseMoveHandler = Function.createDelegate(this, this._onMouseMove);
43
$addHandler(document.body, "mousemove", this._mouseMoveHandler);
44
this._mouseUpHandler = Function.createDelegate(this, this._onMouseUp);
45
$addHandler(document.body, "mouseup", this._mouseUpHandler);
46![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
47
this.get_element().className = this._dragCssClass;
48
},
49
_onMouseMove : function (e)
50![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
51
var ele = this.get_element();
52
ele.style.left = e.clientX - this._diffX;
53
ele.style.top = e.clientY - this._diffY;
54
},
55
_onMouseUp : function ()
56![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
57
// 鼠标释放之后删除body的事件
58
$removeHandler(document.body, "mousemove", this._mouseMoveHandler);
59
$removeHandler(document.body, "mouseup", this._mouseUpHandler);
60
this._diffX = 0;
61
this._diffY = 0;
62
this.get_element().className = "";
63
},
64
65
dispose : function ()
66![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
67
$clearHandlers(document.body);
68
$clearHandlers(this.get_element());
69
Shenba.DragBehavior.callBaseMethod(this, "dispose");
70
}
71
}
72![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
73![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Shenba.DragBehavior.descriptor =
{
74![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
properties: [
{name: "dragCssClass", type: String} ]
75
}
76![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
77
Shenba.DragBehavior.registerClass("Shenba.DragBehavior", Sys.UI.Behavior);
78![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
79
if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
80![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
81![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
82![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
最后在页面中调用就非常的简单,记得添加scriptmanager即可
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Page
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
<%
@ Register Assembly="AjaxControl" Namespace="AjaxControl" TagPrefix="shenba" %>
2
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
3
<div>
4
<asp:Calendar ID="ca" runat="server"></asp:Calendar>
5
<shenba:DragExtender TargetControlID="ca" DragCssClass="drag" ID="dragExtender1" runat="server"/>
6
</div>
目前实现的只是简单拖动,不能像profile那样保存起来,有空再研究下。
完整代码