前言:
Virtual Earth作为微软的地图服务,在技术和实用性上与Google Map有的一拼,某些方面还比Google Map做的要好,用的人也越来越多了。但由于其JavaScript的高度封装特性,最近遇到了不少Virtual Earth与ASP.NET AJAX不兼容的情况。案例既多又复杂,本篇通过一个有代表性的例子来讨论两者的兼容,希望能帮助遇到此麻烦的开发者解决问题。
问题重现:
下面的代码将一个Virtual Earth地图放在一个AJAX Control Toolkit 的Tab Panel里:
<%
@ Page Language
=
"
C#
"
%>
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head id ="Head1" runat ="server" >
< title > Virtual Earth Test </ title >
< script type ="text/javascript" src ="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2" ></ script >
< script type ="text/javascript" >
var map = null ;
function GetMap() {
map = new VEMap( ' myMap ' );
map.LoadMap();
}
function DoZoomIn(c) {
map.ZoomIn();
}
function DoZoomOut() {
map.ZoomOut();
}
function DoCenterZoom() {
var lat = document.getElementById( ' txtMapLat ' ).value;
var lon = document.getElementById( ' txtMapLon ' ).value;
var zoom = document.getElementById( ' zoomLevel ' ).value;
map.SetCenterAndZoom( new VELatLong(lat, lon), zoom);
}
</ script >
</ head >
< body onload ="GetMap();" >
< form id ="form1" runat ="server" >
< div >
< asp:ScriptManager ID ="ScriptManager1" runat ="server" />
< ajaxToolkit:TabContainer ID ="TabContainer1" runat ="server" ActiveTabIndex ="0" >
< ajaxToolkit:TabPanel runat ="server" HeaderText ="Pictures" ID ="TabPanel1" >
< ContentTemplate >
Pictures
</ ContentTemplate >
</ ajaxToolkit:TabPanel >
< ajaxToolkit:TabPanel runat ="server" HeaderText ="Location" ID ="TabPanel2" >
< ContentTemplate >
< div id ='myMap' style ="position:relative; width:350px; height:300px;" ></ div >
< div > Latitude: < input id ='txtMapLat' style ='width: 30px' type ='text' value ='45' /></ div >
< div > Longtidude: < input id ='txtMapLon' style ='width: 30px' type ='text' value ='-120' /></ div >
< div >
Zoom level: < input id ='zoomLevel' type ='text' style ='width:15px;' value ='5' />
< input type ='button' value ='Set center & zoom' onclick ='DoCenterZoom();' />
</ div >
</ ContentTemplate >
</ ajaxToolkit:TabPanel >
</ ajaxToolkit:TabContainer >
</ div >
</ form >
</ body >
</ html >
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head id ="Head1" runat ="server" >
< title > Virtual Earth Test </ title >
< script type ="text/javascript" src ="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2" ></ script >
< script type ="text/javascript" >
var map = null ;
function GetMap() {
map = new VEMap( ' myMap ' );
map.LoadMap();
}
function DoZoomIn(c) {
map.ZoomIn();
}
function DoZoomOut() {
map.ZoomOut();
}
function DoCenterZoom() {
var lat = document.getElementById( ' txtMapLat ' ).value;
var lon = document.getElementById( ' txtMapLon ' ).value;
var zoom = document.getElementById( ' zoomLevel ' ).value;
map.SetCenterAndZoom( new VELatLong(lat, lon), zoom);
}
</ script >
</ head >
< body onload ="GetMap();" >
< form id ="form1" runat ="server" >
< div >
< asp:ScriptManager ID ="ScriptManager1" runat ="server" />
< ajaxToolkit:TabContainer ID ="TabContainer1" runat ="server" ActiveTabIndex ="0" >
< ajaxToolkit:TabPanel runat ="server" HeaderText ="Pictures" ID ="TabPanel1" >
< ContentTemplate >
Pictures
</ ContentTemplate >
</ ajaxToolkit:TabPanel >
< ajaxToolkit:TabPanel runat ="server" HeaderText ="Location" ID ="TabPanel2" >
< ContentTemplate >
< div id ='myMap' style ="position:relative; width:350px; height:300px;" ></ div >
< div > Latitude: < input id ='txtMapLat' style ='width: 30px' type ='text' value ='45' /></ div >
< div > Longtidude: < input id ='txtMapLon' style ='width: 30px' type ='text' value ='-120' /></ div >
< div >
Zoom level: < input id ='zoomLevel' type ='text' style ='width:15px;' value ='5' />
< input type ='button' value ='Set center & zoom' onclick ='DoCenterZoom();' />
</ div >
</ ContentTemplate >
</ ajaxToolkit:TabPanel >
</ ajaxToolkit:TabContainer >
</ div >
</ form >
</ body >
</ html >
结果,我们可以发现,地图出现了问题,没有被正确载入:
解决方案:
在TabContainer 的OnClientActiveTabChanged事件中重新调用GetMap方法生成地图,可以解决此问题:
<
ajaxToolkit:TabContainer
ID
="TabContainer1"
runat
="server"
ActiveTabIndex
="0"
OnClientActiveTabChanged
="GetMap"
>
这次工作正常:
整页代码如下:
<%
@ Page Language
=
"
C#
"
%>
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head id ="Head1" runat ="server" >
< title > Virtual Earth Test </ title >
< script type ="text/javascript" src ="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2" ></ script >
< script type ="text/javascript" >
var map = null ;
function GetMap() {
map = new VEMap( ' myMap ' );
map.LoadMap();
}
function DoZoomIn(c) {
map.ZoomIn();
}
function DoZoomOut() {
map.ZoomOut();
}
function DoCenterZoom() {
var lat = document.getElementById( ' txtMapLat ' ).value;
var lon = document.getElementById( ' txtMapLon ' ).value;
var zoom = document.getElementById( ' zoomLevel ' ).value;
map.SetCenterAndZoom( new VELatLong(lat, lon), zoom);
}
</ script >
</ head >
< body onload ="GetMap();" >
< form id ="form1" runat ="server" >
< div >
< asp:ScriptManager ID ="ScriptManager1" runat ="server" />
< ajaxToolkit:TabContainer ID ="TabContainer1" runat ="server" ActiveTabIndex ="0" OnClientActiveTabChanged ="GetMap" >
< ajaxToolkit:TabPanel runat ="server" HeaderText ="Pictures" ID ="TabPanel1" >
< ContentTemplate >
Pictures
</ ContentTemplate >
</ ajaxToolkit:TabPanel >
< ajaxToolkit:TabPanel runat ="server" HeaderText ="Location" ID ="TabPanel2" >
< ContentTemplate >
< div id ='myMap' style ="position: relative; width: 350px; height: 300px;" >
</ div >
< div >
Latitude: < input id ='txtMapLat' style ='width: 30px' type ='text' value ='45' /></ div >
< div >
Longtidude: < input id ='txtMapLon' style ='width: 30px' type ='text' value ='-120' /></ div >
< div >
Zoom level: < input id ='zoomLevel' type ='text' style ='width: 15px;' value ='5' />
< input type ='button' value ='Set center & zoom' onclick ='DoCenterZoom();' />
</ div >
</ ContentTemplate >
</ ajaxToolkit:TabPanel >
</ ajaxToolkit:TabContainer >
</ div >
</ form >
</ body >
</ html >
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head id ="Head1" runat ="server" >
< title > Virtual Earth Test </ title >
< script type ="text/javascript" src ="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2" ></ script >
< script type ="text/javascript" >
var map = null ;
function GetMap() {
map = new VEMap( ' myMap ' );
map.LoadMap();
}
function DoZoomIn(c) {
map.ZoomIn();
}
function DoZoomOut() {
map.ZoomOut();
}
function DoCenterZoom() {
var lat = document.getElementById( ' txtMapLat ' ).value;
var lon = document.getElementById( ' txtMapLon ' ).value;
var zoom = document.getElementById( ' zoomLevel ' ).value;
map.SetCenterAndZoom( new VELatLong(lat, lon), zoom);
}
</ script >
</ head >
< body onload ="GetMap();" >
< form id ="form1" runat ="server" >
< div >
< asp:ScriptManager ID ="ScriptManager1" runat ="server" />
< ajaxToolkit:TabContainer ID ="TabContainer1" runat ="server" ActiveTabIndex ="0" OnClientActiveTabChanged ="GetMap" >
< ajaxToolkit:TabPanel runat ="server" HeaderText ="Pictures" ID ="TabPanel1" >
< ContentTemplate >
Pictures
</ ContentTemplate >
</ ajaxToolkit:TabPanel >
< ajaxToolkit:TabPanel runat ="server" HeaderText ="Location" ID ="TabPanel2" >
< ContentTemplate >
< div id ='myMap' style ="position: relative; width: 350px; height: 300px;" >
</ div >
< div >
Latitude: < input id ='txtMapLat' style ='width: 30px' type ='text' value ='45' /></ div >
< div >
Longtidude: < input id ='txtMapLon' style ='width: 30px' type ='text' value ='-120' /></ div >
< div >
Zoom level: < input id ='zoomLevel' type ='text' style ='width: 15px;' value ='5' />
< input type ='button' value ='Set center & zoom' onclick ='DoCenterZoom();' />
</ div >
</ ContentTemplate >
</ ajaxToolkit:TabPanel >
</ ajaxToolkit:TabContainer >
</ div >
</ form >
</ body >
</ html >
微软经常弄出自己的产品之间不兼容的囧事,不过也难为微软了,有着全球最庞大的客户队伍,产品涉及面极广,并且每个产品都尽量做到极高程度的封装,实在不易。