03

27

关于自定义任务(Tasks)的心得

1、类简介
在ADF中,提供了任务管理器控件(TaskManager)以及任务结果控件(TaskResults)。任务管理器控件可以容纳ADF中提供的一系列任务控件(如:SearchAttributesTask/QueryAttributesTask/FindPlaceTask/FindAddressTask/GeoprocessingTask/EditorTask),我们自定义的任务控件也可以放置在内。
自定义任务控件一般是从任务抽象类(Task或者FloatingPanelTask)继承而来。FloatingPanelTask与Task的相同之处在于它们都是从System.Web.UI.WebControls.CompositeControl继承而来,而System.Web.UI.WebControls.CompositeControl实现了ICallbackEventHandler接口,所以它们都具有Ajax能力。
FloatingPanelTask与Task的区别在于是否被包含在FloatingPanel中。所以以下重点谈谈任务抽象类Task。Task类除了实现ICallbackEventHandler外,还实现了二个接口:IBuddyControlSupport以及ITask。
(1)IBuddyControlSupport接口定义了方法GetSupportedBuddyControlTypes,来说明任务绑定的空间类型。如OverviewMap控件绑定Map, Toolbar控件绑定Map以及PageLayout控件。我们如果对Map操作,则可以使用如下代码:
public Type[] GetSupportedBuddyControlTypes() {return new Type[] { typeof(Map) };}
(2)ITask接口
主要属性以及方法
object Input { get; set;}
提交前后的参数。由于Task继承于CompositeControl,因此会将变量参数内容存储在变量_callbackArg中。所以一般在GetCallbackResult()中会利用_callbackArg生成Input内容。所生成的生成Input内容一般在ExecuteTask()中进行使用。
object Results { get;set;}
    任务所生成的结果。一般在ExecuteTask()中生成。在类FloatingPanelTask中方法GetCallbackResult()中会调用DisplayResults(taskJobID, Input, Results),而DisplayResults则对任务结果控件进行结果遍历显示resultsContainer.DisplayResults(this, jobID, taskInput, taskResults);
CallbackResultCollection CallbackResults { get;}
回调结果集合。在DisplayResults(taskJobID, Input, Results)调用任务结果控件进行结果遍历显示后,会执行CallbackResults.CopyFrom(resultsContainer.CallbackResults)来进行回调登记。在类FloatingPanelTask中方法GetCallbackResult()中会执行CallbackResults.ToString()来产生下一次回调内容。
除了实现以上两个接口的内容外,自定义任务很重要的一个方法是CreateChildControls()方法。为了将子控件增加到控件集合中去,必须重写受保护的CreateChildControls()方法。在这个方法中,我们使用Controls.Add()方法添加每个子控件到控件树中。当然,为了避免子控件与页面其他控件之间的命名冲突,我们使用INamingContainer接口。
2、示例Common_CustomTask_CSharp简说
(1)在CreateChildControls ()中有关任务执行按钮的代码:
string argument = string.Format("'bufferdistance=' + document.getElementById('{0}').value", distanceInput.ClientID);
string onClick = string.Format("executeTask({0},\"{1}\");", argument, CallbackFunctionString);
button.Attributes.Add("onclick", onClick);
在这里,按钮的Click事件激发了executeTask方法。产生的参数如下:
WebForm_DoCallback('TaskManager1$SimpleTask_CSharp1',argument,processCallbackResult,context,postBackError,true)");"
executeTask方法存在于display_task.js中。以下为相关代码:
var taskJobIDCounter = 0;
function executeTask(callbackArguments, callbackFunctionString, taskJobID)
{
    if (taskJobID == null)
    {
        taskJobIDCounter++;
        taskJobID = taskJobIDCounter;
    }
    
    startActivityIndicator(callbackArguments, callbackFunctionString, taskJobID);
    var tmp="startJob(\"" + callbackArguments.replace('\"','\\"') + "\",\"" + callbackFunctionString + "\"" + "," + taskJobID + ")";
    window.setTimeout(tmp,1000);
}
function startActivityIndicator(callbackArguments, callbackFunctionString, taskJobID)
{  
    var argument = "EventArg=startTaskActivityIndicator&taskJobID=" + taskJobID;
    if (callbackArguments.length > 0) argument += "&" + callbackArguments;
var context = null;
//发出WebForm_DoCallback调用,
//argument为"EventArg=startTaskActivityIndicator&taskJobID="+taskJobID; +callbackArguments
    eval(callbackFunctionString);
}
function startJob(callbackArguments, callbackFunctionString, taskJobID)
{
    var argument = "EventArg=executeTask&taskJobID=" + taskJobID;
    if (callbackArguments.length > 0) argument += "&" + callbackArguments;
        var context = null;
//发出WebForm_DoCallback调用,
//argument为"EventArg=executeTask&taskJobID=" + taskJobID;"+ callbackArguments
        eval(callbackFunctionString);
}
很显然,display_task.js中的executeTask()方法引起了Ajax形式的CallBack。产生的字符串为"EventArg=executeTask&taskJobID=2& bufferdistance=10"
  (2)由于Task继承于CompositeControl,因此会将变量参数内容存储在变量_callbackArg中。一般在GetCallbackResult()中会利用_callbackArg生成Input内容。
NameValueCollection keyValColl = CallbackUtility.ParseStringIntoNameValueCollection(_callbackArg);
if (keyValColl["EventArg"] == "executeTask")
{
     string sDistance = keyValColl["bufferdistance"];
      float fDistance;
      float.TryParse(sDistance, out fDistance);
      object[] inputs = new object[2];
      inputs[0] = fDistance;
      ElementGraphicsLayer clonedLayer = GraphicsLayer.Clone() as ElementGraphicsLayer;
      foreach (DataRow row in GraphicsLayer.Rows) clonedLayer.ImportRow(row);
     inputs[1] = clonedLayer;
      GraphicsLayer.Clear();
     input = inputs;
}
(3)所生成的生成Input内容一般在ExecuteTask()中进行使用。
object[] inputs = Input as object[];
//buffer distance
float bufferdistance = (float)inputs[0];
if (float.IsNaN(bufferdistance)) bufferdistance = 0.0F;
ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer inputLayer = inputs[1] as ElementGraphicsLayer;
if (inputLayer == null)  return;
。。。。。。
3、建议参考的其它示例:
(1)
http://blogs.esri.com/Dev/blogs/ ... lts-in-a-table.aspx
(2)
http://arcscripts.esri.com/details.asp?dbid=15133
(3)
http://blogs.esri.com/Dev/blogs/ ... nt-Task-Sample.aspx



文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: GIS Code ArcGIS Server
相关日志:
评论: 0 | 引用: 0 | 查看次数: -
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.