在esri-ajax环境中涮新asp.net显示控件的通用方法

原来一直在esri的server论坛潜水,刚到esri-china server 论坛来学习,发现有不少人被esri-ajax困惑。我以前也被这个问题搞得晕头转向,现在基本明白原理了。

(1)arcgis server 9.2 开始为解决有map页面的局部刷新问题,在asp net 2.0 callback机制的基础上扩充引入了esri-ajax机制,基本上所有与map 有关的控件如map,toc,taskresult等均引入了esri-ajax,这样在有这些esri-ajax机制的esri控件的页面中,原asp.net显示控件涮新方法不能再使用原服务器端的refresh,应由client与server端的互动才行。

(2)mircosoft为解决asp net 2.0 callback机制的难用问题,后推出了ms ajax extention 1.0,使得asp net上的ajax实现大为简单,可惜arcgis server 9.2是在ms ajax extention 1.0(http://asp.net/ajax/downloads/default.aspx)推出前的产品,不支持它,arcgis server 9.3会支持ms ajax extention技术,目前要实现有esri控件与原aspnet 2.0控件页面的全部局部涮新,需同时使用ms ajax与esri asjx,它们的共存是没有问题的(Using ASP.NET AJAX with the Web ADF,见 http://blogs.esri.com/Dev/blogs/ ... th-the-Web-ADF.aspx),我已在一个完整的web gis环境中使用过了,效果与稳定性均令人满意。

(3)如何在esri-ajax环境中涮新asp.net显示控件呢,使用下面的通用方法:

private CallbackResult RefreshControlHtml(Control control)

{

System.IO.StringWriter sw = new System.IO.StringWriter();

HtmlTextWriter writer = new HtmlTextWriter(sw);

control.RenderControl(writer);

string htmlContent = sw.ToString();

sw.Close();

return new CallbackResult(control, "content", htmlContent);

}

在gridview,listbox,label等asp.net显示控件需涮新时,调用:

map1.CallbackResults.Add(RefreshControlHtml(mygridview1));

或 map1.CallbackResults.Add(RefreshControlHtml(mylistbox1));等

-------------------------------------------------------------------------------------------------------------------------------

为示范起见,我贴部分代码。

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using ESRI.ArcGIS.ADF.Web.UI.WebControls;

using ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools;

using ESRI.ArcGIS.ADF.Web;

using ESRI.ArcGIS.ADF;

using System.Collections;

using ESRI.ArcGIS.ADF.Web.Display.Graphics;

using ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer;

using ESRI.ArcGIS.ADF.ArcGISServer;

/// <summary>

/// Command_wsh3 的摘要说明

/// </summary>

public class Command_wsh3 : IMapServerCommandAction

{

public void ServerAction(ToolbarItemInfo info)

{

Map mapctrl = (Map)info.BuddyControls[0];

// 0. 找到 查询条件定义控件

FloatingPanel myfloatingpanel = (FloatingPanel) mapctrl.Page.FindControl("FloatingPanel1");

DropDownList mydroplist1 = (DropDownList)myfloatingpanel.FindControl("DropDownList1");

int myDropindexVlaue = mydroplist1.SelectedIndex;

string jsfunction = string.Format("alert('My Result:{0}');", myDropindexVlaue.ToString());

CallbackResult showcr = new CallbackResult(null, null, "javascript", jsfunction);

mapctrl.CallbackResults.Add(showcr);

// 1.用query方法得到datatable

System.Data.DataTable qdatatable=new DataTable();

IEnumerable func_enum = mapctrl.GetFunctionalities();

foreach (ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality gisfunctionality in func_enum)

{

ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource = gisfunctionality.Resource;

bool supported = gisresource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality));

if (supported)

{

ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality qfunc;

qfunc = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisresource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);

string[] lids;

string[] lnames;

qfunc.GetQueryableLayers(null, out lids, out lnames);

ESRI.ArcGIS.ADF.Web.Geometry.Envelope env = new ESRI.ArcGIS.ADF.Web.Geometry.Envelope(-100, -100, 100, 100);

env = mapctrl.Extent;

ESRI.ArcGIS.ADF.Web.SpatialFilter spatialfilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter();

spatialfilter.Geometry = env;

spatialfilter.ReturnADFGeometries = true;

spatialfilter.MaxRecords = 1000;

for (int i = 0; i < lids.Length; i++)

{

// if (i == 1) // 主要机构

if ( i== 1 )

{

qdatatable = qfunc.Query(null, lids, spatialfilter);

// qdatatable.TableName = gisresource.Name + "_" + lnames;

qdatatable.TableName = lnames + " (当前区域: " + qdatatable.Rows.Count.ToString() + ")";

}

}

}

}

// 2 在datatable中加入一个LINK字段指示详情

// 3 把 datatable Converter To GraphicsLayer

// 4 把GraphicsLayer中的IsSelectedColumn字段set true

// 5 把 graphicsLayer 加载 到 mapresource

// 6 refresh map

if (mapctrl.ImageBlendingMode == ImageBlendingMode.WebTier)

{

mapctrl.Refresh();

}

else

if (mapctrl.ImageBlendingMode == ImageBlendingMode.Browser)

{

mapctrl.RefreshResource(gResource.Name);

}

// 7- 把dataset放入 taskresult

// 8- 刷新taskresult

myTaskResults.Refresh();

foreach (CallbackResult cr in myTaskResults.CallbackResults)

{

mapctrl.CallbackResults.Add(cr);

}

// 9 - 用 gridview 显示 graphicsLayer

GridView mygridview1 = (GridView)mapctrl.Page.FindControl("GridView1");

mygridview1.DataSource = graphicsLayer;

mygridview1.DataBind();

mapctrl.CallbackResults.Add(RefreshControlHtml(mygridview1));

TextBox mytextbox = (TextBox)mapctrl.Page.FindControl("TextBox1");

mytextbox.Text = "当前区域:" + qdatatable.Rows.Count.ToString();

mapctrl.CallbackResults.Add(RefreshControlHtml(mytextbox));

}

private CallbackResult RefreshControlHtml(Control control)

{

System.IO.StringWriter sw = new System.IO.StringWriter();

HtmlTextWriter writer = new HtmlTextWriter(sw);

control.RenderControl(writer);

string htmlContent = sw.ToString();

sw.Close();

return new CallbackResult(control, "content", htmlContent);

}

}