myrailway empire修改器修改 请教如何把状态栏修改成

4发现相似题今日推荐:
宾语从句专题训练
作者:佚名&&&&文章来源:本站原创&&&&更新时间:
基本型 1.&He&won’t&come.&I&think.&(变为复合句)(1996甘肃) I&______&think&he&______&come. 2.&Miss&Gao:&Lucy,&do&you&come&from&the&USA?&(改为含有宾语从句的句子) Miss&Gao&asked&Lucy&that&she&came&from&the&USA. Miss&Gao&asked&Lucy&do&you&come&from&the&USA. Miss&Gao&asked&Lucy&if&she&came&from&the&USA. 3.&“Do&you&wash&your&clothes&yourself?”&Tom&asked&the&girl&next&to&him.(改复合句) Tom&asked&the&girl&next&to&him&______&______&______&her&clothes&herself. 4.&Did&Peter&come&here&yesterday?&Li&Lei&wants&to&know.&(改为宾从)(1999福州) Li&Lei&wants&to&know&______&Peter&______&here&yesterday. 5.&Is&the&earth&round?&The&little&boy&asked.(改为宾语从句) The&little&boy&asked&______&the&earth&______&round. 6.&“Where&does&he&live?”&Mr&Hu&asked.(改为复合句) Mr&Hu&asked&where&_______&_______. 7.&Tom’s&father&saw&him&sitting&on&some&eggs.(改为复合句) Tom’s&father&saw&______&______&______&sitting&on&some&eggs. 8.&Mrs&White&told&Tom&not&to&throw&paper&on&the&ground.(改为复合句)&(99上海) Mrs&white&told&Tom&______&______&______&throw&paper&on&the&ground. 9.&Please&tell&me&where&we&show&our&tickets.(改为简单句,保持原意)&(98广西) Please&tell&me&______&______&show&our&tickets. 10.&Can&you&tell&me&how&I&can&get&to&the&post&office?&(改为简单句,保持原意)& Can&you&tell&me&the&______&_____&the&post&office? 11.&Rose&doesn’t&know&when&they&are&going&to&repair&the&watch.&(改为简单句) Rose&doesn’t&know&______&______&repair&the&watch. 12.&The&teacher&told&the&boys&what&they&should&do&and&how&they&should&do&it.(改为简单句) The&teacher&told&the&boys&______&______&do&and&______&_____&do&it. 13.&The&earth&moves&around&the&sun.&The&teacher&said.(改为宾语从句) The&teacher&said&______&the&earth&______&around&the&sun. 14.&Are&you&hungry?&My&mother&asked&me.(改为宾语从句) My&mother&asked&me&______&______&______&hungry. 15.&Why&hasn’t&she&come&yet?&Nobody&knows.&(改为宾语从句) Nobody&knows&______&______&_______&come&yet. 提高型 1.&I&don’t&know&_____&he&will&come&tomorrow.&_____&he&comes,&I’ll&tell&you. A.&&WhetherB.&&WhetherC.&&ThatD.&&if& 2.&Could&you&tell&me&____&the&radio&without&any&help? A.&how&did&he&mendB.&what&did&he&mend C.&how&he&mendedD.&what&he&mended 3.&Could&you&tell&me&____&do&with&the&money? A.&how&toB.&what&should&IC.&how&I&shouldD.&what&I&should 4.&Can&you&tell&me&how&many&English&words&____&since&1996? A.&have&you&learnedB.&did&you&learn&C.&you&have&learnedD.&you&learned 5.&Miss&Li&wants&to&know&_____&next&week. A.&when&my&uncle&leavesB.&when&will&my&uncle C.&where&my&uncle&will&stayD.&where&does&my&uncle&stay 6.&Can&you&tell&me&when&____? A.&does&the&ship&leaveB.&the&ship&will&leave C.&the&ship&leaveD.&will&the&ship&leave 7.&Alice&wanted&to&know&____&her&grandmother&liked&the&bag. A.&thatB.&ifC.&whichD.&what 8.&I&don’t&know&____&Jane&was&late&for&school&this&morning. A.&whoB.&whatC.&whomD.&why 9.&They&don’t&know&____&their&presents&are. A.&whenB.&whyC.&what 10.&Mike&asked&the&girl&in&the&shop&____&the&watch&____&cheap&enough.(1998云南) A.&&isB.&&wasC.&&wasD.&&is 11.&I&think&he&____&back&next&week. A.&comeB.&will&comeC.&cameD.&has&come 12.&Xiao&Mao&told&me&he&____&a&film&with&his&mother&the&next&day. A.&would&seeB.&will&watchC.&would&lookD.&will&see 13.&Could&you&tell&me&if&it&____&tomorrow? A.&rainB.&will&rainC.&rainingD.&rains 14.&He&said&that&he&____&speak&a&little&English&when&he&was&five. A.&mightB.&wouldC.&couldD.&can 15.&I&want&to&know&if&they&____&the&spring&sports&meeting&next&month.& If&they&____&it,&I&must&get&ready&for&it. A.&&will&holdB.&will&&hold&C.&&holdD.&will&&will&hold 综合型 1.&CDo&you&remember&____&he&came?-Yes,&I&do,&he&came&by&car. A.&how&B.&whenC.&thatD.&if 2.&That&woman&wanted&to&know&_____&her&daughter&liked&the&sweater. A.&whetherB.&whatC.&thatD.&which 3.&Have&you&decided&when&_____&for&London? A.&will&you&leaveB.&you&will&leaveC.&are&you&goingD.&you&are&going 4.&CExcuse&me.&Could&you&tell&me&____?&-Certainly. A.&when&can&I&get&to&the&stationB.&I&can&get&to&which&station C.&which&station&can&I&get&toD.&how&I&can&get&to&the&station 5.&CWhat&did&your&mother&say,&Tom?&-She&asked&me&why&____. A.&my&sister&cryingB.&my&sister&was&crying C.&is&my&sister&cryingD.&was&my&sister&crying 6.&I&wonder&what&time&_____&arrive. A.&does&the&trainB.&will&the&train&C.&the&trainD.&the&train&will 7.&I&wondered&_____&our&teacher&did&that&for. A.&thatB.&ifC.&whatD.&why 8.&Did&you&hear&_____? A.&what&did&I&sayB.&what&I&saidC.&that&I&saidD.&I&said&which 9.&Can&you&tell&me&which&room&_____? A.&does&he&live&inB.&does&he&livesC.&he&lives&inD.&he&lives 10.&The&little&boy&often&asks&me&what&______? A.&will&our&life&of&tomorrowB.&will&our&life&tomorrow&be&like C.&our&life&of&tomorrow&likeD.&our&life&of&tomorrow&will&be&like 11.&Do&you&really&know&_____&used? A.&how&widely&English&isB.&how&wide&is&English C.&English&is&how&widelyD.&how&is&English&wide 12.&Would&you&please&tell&me&______&with&Peter?&He&looks&unhappy. A.&what’s&the&matterB.&what&wrong&is C.&the&wrong&is&whatD.&what&wrong&it&was 13.&CExcuse&me,&where&_____?&Do&you&know?&-Yes.&I&know&where&_____? A.&Jim&&he&livesB.&does&Jim&&do&he&live C.&Jim&&does&he&liveD.&does&Jim&&he&lives 14.&I&didn’t&know&_____&and&_____. A.&what’s&his&&how&old&he&isB.&what&his&name&&how&old&he&was C.&what&his&name&&how&is&he&oldD.&that&was&his&&he&was&how&old 15.&My&friend&hasn’t&decided&_____&on&a&trip&to&Wuxi&on&holiday. A.&if&he&goesB.&when&will&he&go&C.&if&he’ll&go&D.&where&he&go 16.&Did&you&ask&her&what&______&outside? A.&was&happened&to&himB.&he&had&happened C.&he&happenedD.&had&happened&to&him 17.&The&man&in&the&shop&asked&the&woman&_____ A.&which&kind&does&she&likeB.&which&kind&she&is C.&which&kind&is&she&likesD.&which&kind&she&likes 18.&No&one&told&us&_____,&so&we&need&your&help. A.&how&should&we&doB.&what&should&we&do C.&how&to&do&itD.&what&to&do&it 19.&I&don’t&know&______&the&day&after&tomorrow. A.&when&does&he&comeB.&how&will&he&come C.&if&he&comesD.&whether&he’ll&come 20.&CCould&you&tell&me&_____?-Yes,&they&_____&to&the&library. A.&where&are&the&&have&beenB.&where&the&twins&&have&gone C.&where&were&the&&have&been&D.&where&the&twins&&have&gone&
【】【】【】【】
上一篇文章: 下一篇文章:
80276153154390028211054760871600博客分类:
android 自动检测版本在这里就不用说了,今天想和大家一起分享的是如何将下载更新文件最小化到任务栏下载,替代掉丑陋的对话框提示下载,对话框提示下载的用户体验相当不好,我们把它修改成为后台下载这样可以改善用户的使用体验。
废话就不多说了,直接贴代码。首先要创建一个Service来执行下载更新文件的任务:
public class UpdateService extends Service{
private NotificationM
private Notif
private File tempFile=
private boolean cancelUpdate=
private MyHandler myH
private int download_precent=0;
private RemoteV
private int notificationId=1234;
public IBinder onBind(Intent intent) {
public void onStart(Intent intent,int startId){
super.onStart(intent, startId);
public int onStartCommand(Intent intent,int flags,int startId){
nm=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notification=new Notification();
notification.icon=android.R.drawable.stat_sys_
//notification.icon=android.R.drawable.stat_sys_download_
notification.tickerText=getString(R.string.app_name)+"更新";
notification.when=System.currentTimeMillis();
notification.defaults=Notification.DEFAULT_LIGHTS;
//设置任务栏中下载进程显示的views
views=new RemoteViews(getPackageName(),R.layout.update);
notification.contentView=
PendingIntent contentIntent=PendingIntent.getActivity(this,0,new Intent(this,City.class),0);
notification.setLatestEventInfo(this,"","", contentIntent);
//将下载任务添加到任务栏中
nm.notify(notificationId,notification);
myHandler=new MyHandler(Looper.myLooper(),this);
//初始化下载任务内容views
Message message=myHandler.obtainMessage(3,0);
myHandler.sendMessage(message);
//启动线程开始执行下载任务
downFile(intent.getStringExtra("url"));
return super.onStartCommand(intent, flags, startId);
public void onDestroy(){
super.onDestroy();
//下载更新文件
private void downFile(final String url) {
new Thread() {
public void run(){
HttpClient client = new DefaultHttpClient();
// params[0]代表连接的url
HttpGet get = new HttpGet(url);
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream is = entity.getContent();
if (is != null) {
File rootFile=new File(Environment.getExternalStorageDirectory(), "/pinke");
if(!rootFile.exists()&&!rootFile.isDirectory())
rootFile.mkdir();
tempFile = new File(Environment.getExternalStorageDirectory(),
"/pinke/"+url.substring(url.lastIndexOf("/")+1));
if(tempFile.exists())
tempFile.delete();
tempFile.createNewFile();
//已读出流作为参数创建一个带有缓冲的输出流
BufferedInputStream bis = new BufferedInputStream(is);
//创建一个新的写入流,讲读取到的图像数据写入到文件中
FileOutputStream fos = new FileOutputStream(tempFile);
//已写入流作为参数创建一个带有缓冲的写入流
BufferedOutputStream bos = new BufferedOutputStream(fos);
long count=0;
int precent=0;
byte[] buffer=new byte[1024];
while( (read = bis.read(buffer)) != -1 && !cancelUpdate){
bos.write(buffer,0,read);
precent=(int)(((double)count/length)*100);
//每下载完成5%就通知任务栏进行修改下载进度
if(precent-download_precent&=5){
download_precent=
Message message=myHandler.obtainMessage(3,precent);
myHandler.sendMessage(message);
bos.flush();
bos.close();
fos.flush();
fos.close();
is.close();
bis.close();
if(!cancelUpdate){
Message message=myHandler.obtainMessage(2,tempFile);
myHandler.sendMessage(message);
tempFile.delete();
} catch (ClientProtocolException e) {
Message message=myHandler.obtainMessage(4,"下载更新文件失败");
myHandler.sendMessage(message);
} catch (IOException e) {
Message message=myHandler.obtainMessage(4,"下载更新文件失败");
myHandler.sendMessage(message);
} catch(Exception e){
Message message=myHandler.obtainMessage(4,"下载更新文件失败");
myHandler.sendMessage(message);
}.start();
//安装下载后的apk文件
private void Instanll(File file,Context context){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
context.startActivity(intent);
/*事件处理类*/
class MyHandler extends Handler{
public MyHandler(Looper looper,Context c){
super(looper);
this.context=c;
public void handleMessage(Message msg){
super.handleMessage(msg);
if(msg!=null){
switch(msg.what){
Toast.makeText(context,msg.obj.toString(), Toast.LENGTH_SHORT).show();
//下载完成后清除所有下载信息,执行安装提示
download_precent=0;
nm.cancel(notificationId);
Instanll((File)msg.obj,context);
//停止掉当前的服务
stopSelf();
//更新状态栏上的下载进度信息
views.setTextViewText(R.update_id.tvProcess,"已下载"+download_precent+"%");
views.setProgressBar(R.update_id.pbDownload,100,download_precent,false);
notification.contentView=
nm.notify(notificationId,notification);
nm.cancel(notificationId);
下载更新提示的布局xml:
&?xml version="1.0" encoding="utf-8"?&
&LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#f2f2f2" &
&LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"&
&ImageView
android:id="@+update_id/ivLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/logo"
android:layout_margin="10dip" /&
&LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1"
android:layout_marginRight="10dip"&
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/deepblack"
android:text="@string/app_name"
android:textSize="18dip"
android:textStyle="bold"/&
&ProgressBar
android:id="@+update_id/pbDownload"
android:layout_width="fill_parent"
android:layout_height="12dip"
android:progress="0"
android:max="100"
android:progressDrawable="@drawable/pb_style"
style="?android:attr/progressBarStyleHorizontal"
mce_style="?android:attr/progressBarStyleHorizontal"
android:id="@+update_id/tvProcess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/deepblack"
android:text="已下载0%"
android:textSize="12dip"
android:textStyle="bold" /&
&/LinearLayout&
&/LinearLayout&
&/LinearLayout&
在外面需要调用下载任务的地方使用startService(intent)来调用这个Service就可以了,最终的效果图片
WilliamLiu
浏览: 14678 次
来自: 成都
就这样也详解?
不错,受教了,以下还有不同的说法:http://www.ite ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'当前位置: >>
ArcGIS Engine开发实践
《ArcGIS Engine+C#实例开发教程》第七讲 图层符号选择器的实现第一讲:桌面 GIS 应用程序框架的建立本讲主要是使用 MapControl、PageLayoutControl、ToolbarControl、TOCControl 四个控件建立 起基本的桌面 GIS 应用程序框架。最终成果预览如下:1、新建项目 启动 VS2005,选择“文件|新建|项目” ,在项目类型中选择 Visual C#,再选择 Windows 应用 程序模板,输入名称“3sdnMap” ,点击确定。 在解决方案管理器中将“Form1.cs”重命名为“3sdnMap.cs” ,在设计视图中,选中窗体, 将其属性中的“Text”改为“3sdnMap” 。2、添加控件 选择工具箱中的“菜单和工具栏|MenuStrip” ,将其拖入窗体。 选择工具箱中的“ArcGIS Windows Forms”节,将“ToolbarControl”控件拖入窗体,并将其 属性中的 Dock 设置为 Top。 选择工具箱中的“菜单和工具栏|StatusStrip” ,将其拖入到窗体。 选择工具箱中的“容器|SplitContainer”容器拖入窗体,并将其属性中的 Dock 设置为 Fill。 将 TabControl 控件拖入 Panel1,将 Alignment 属性设置为 Bottom,Dock 属性设置为 Fill。点 击 TabPages 属性右边的按钮,弹出 TabPage 集合编辑器,将 tabPage1 的 Name 设置为 tabPageLayer,Text 设置为图层,将 tabPage2 的 Name 设置为 tabPageProperty,Text 设置为 属性。如下所示。 选择“图层”选项卡,拖入 TOCControl 控件,设置 Dock 属性为 Fill。 选择“属性”选项卡,拖入 DataGridView 控件,设置 Dock 属性为 Fill。 拖入 TabControl 控件到 Panel2,设置 Dock 属性为 Fill。并上述类似的方法,将两个选项卡的 Name 和 Text 分别设置为: (tabPageMap、地图)(tabPageLayout,制版) , 。 选择“地图”选项卡,拖入 MapControl 控件,设置 Dock 属性为 Fill。 选择“制版”选项卡,拖入 PageLayoutControl 控件,设置 Dock 属性为 Fill。 最后将 LicenseControl 控件拖入到窗体的任意地方。 按 F5 编译运行,可以看到刚才布局好的程序界面了。3、控件绑定 通过以上步骤添加的控件还只是单独存在, 而我们的程序需要各控件间协同工作, 因此要进 行控件绑定。 分别右击 ToolbarControl、TOCControl 控件,将 Buddy 设置为 axMapControl1,如下图所示。 这样,工具条和图层控件就与地图控件关联了。4、添加工具 此时,工具条中还没有任何工具,添加的方法也很简单。右击 ToolbarControl,选择“属性 |Items” ,点击 Add,选择 Commands 选项卡中的 Generic,双击 Open、SaveAs、Redo、Undo 即可将相应工具添加到工具条。常见的工具有: Map Navigation 中的导航工具,Map Inquiry 中的查询工具,Feature Selection 中的选择工具, 你可以根据需要酌情添加工具。 5、编译运行 按 F5 即可编译运行程序,至此桌面 GIS 应用程序框架基本框架已经搭建好了,你可以通过 工具条的工具打开地图文档,浏览地图了,效果如开篇所示.第二讲 菜单的添加及其实现摘要: 在上一讲中, 我们实现了应用程序基本框架, 其中有个小错误, 在此先跟大家说明下。 在“属性”选项卡中,我们当时添加的是 DataGridView 控件,这个控件是用来显示数据表 的,而专门用于属性的查询和设置的控件是 PropertyGrid 控件。因此请你删除“属性”选 项卡中的 DataGridView 控件,再把位于“工具箱 | 所有 Windows 窗体 |PropertyGrid ” (如果没有,右击选择“选择项”以添加此控件)控件拖到该选项卡。 在上一讲中, 我们实现了应用程序基本框架, 其中有个小错误, 在此先跟大家说明下。 “属 在 性”选项卡中,我们当时添加的是 DataGridView 控件,这个控件是用来显示数据表的,而 专门用于属性的查询和设置的控件是 PropertyGrid 控件。因此请你删除“属性”选项卡中 的 DataGridView 控件,再把位于“工具箱 | 所有 Windows 窗体 |PropertyGrid ” (如果 没有,右击选择“选择项”以添加此控件)控件拖到该选项卡。 在这一讲中,主要讲解菜单的添加和实现。 1、 添加菜单 在设计视图中,单击菜单栏,会出现“请在此处键入”的提示,单击提示就可以键入菜单名 称,如“文件” ,再单击“文件” ,即可输入其下拉子菜单,如下所示:Tips : 每创建一个菜单,请在其属性面板中设置 Name 属性,而且不要为中文,因此 Name 值将 是此菜单响应函数的函数名的一部分,带中文的函数名,总是不好吧。 本讲中, 我们将添加新建 New ) 打开 Open ) 添加数据 AddData ) 保存 Save ) ( 、 ( 、 ( 、 ( 、 另存为( SaveAs ) 、退出( Exit )这些菜单, ()内为相应的 Name 属性值。 Tips: 你可以在属性面板中的 Text 属性中,把菜单名设置为中英文形式,如“打开 O pen ” ,带 下划线的 O 表示此项菜单的快捷键是字母 O , 设置方法是在相应字母前加上 & ” “ 字符, 如“打开 &Open ” 。但这种快捷键只在打开此下拉菜单时才有效,即当你单击“文件”菜 单弹出下拉菜单时,按下字母 O 就可以定位到“打开”菜单。 还有一种在程序运行时都有效的全局快捷键,可以在属性面板中的“ ShortCutKeys ”中设 置。 你还可以在属性面板中的 Image 属性中设置你喜欢的菜单图标。 单击 Image 那一行右边的 按钮,弹出如下菜单。选择“项目资源文件” ,再单击导入就可以选择你的图标了。最终效果如下所示。 注意, 在解决方案面板中, 选中刚才添加的所有图标, 在其属性面板中将生成操作设置为 “嵌 入的资源” ,这一点很重要! 2、 实现相关菜单 首先定义指针(写在 public partial class Form1 : Form 下面即可) :private ESRI.ArcGIS.Controls.IMapControl3 m_mapControl = private ESRI.ArcGIS.Controls.IPageLayoutControl2 m_pageLayoutControl = private IMapDocument pMapD若以上指针无效,请添加以下引用:using ESRI.ArcGIS.C using ESRI.ArcGIS.C using ESRI.ArcGIS.esriS using ESRI.ArcGIS.D using ESRI.ArcGIS.G using ESRI.ArcGIS.SystemUI;在设计视图中的属性面板中,选择 Form1 ,即主窗体,单击事件按钮(闪电形状的那个按 钮) ,打到“ Load ”事件并双击,添加此事件。 在 Form1_Load 函数中初始化这些指针: // 取得 MapControl 和 PageLayoutControl 的引用m_mapControl = (IMapControl3)this.axMapControl1.O m_pageLayoutControl = (IPageLayoutControl2)this.axPageLayoutControl1.O 依次双击每个菜单项,添加菜单响应函数。实现代码如下:/// &summary& /// 新建地图命令 /// &/summary& /// &param name=&sender&&&/param& /// &param name=&e&&&/param& private void New_Click(object sender, EventArgs e) { // 本命令涉及到 MapControl 和 PageLayoutControl 同步问题,将在下一讲中实现 } /// &summary& /// 打开地图文档 Mxd 命令 /// &/summary& /// &param name=&sender&&&/param& /// &param name=&e&&&/param& private void Open_Click(object sender, EventArgs e) { // 本命令涉及到 MapControl 和 PageLayoutControl 同步问题,将在下一讲中实现 } /// &summary& /// 添加数据命令 /// &/summary& /// &param name=&sender&&&/param& /// &param name=&e&&&/param& private void AddData_Click(object sender, EventArgs e) { int currentLayerCount = this.axMapControl1.LayerC ICommand pCommand = new ControlsAddDataCommandClass(); pCommand.OnCreate(this.axMapControl1.Object); pCommand.OnClick(); } /// &summary& /// 保存地图文档命令 /// &/summary& /// &param name=&sender&&&/param& /// &param name=&e&&&/param& private void Save_Click(object sender, EventArgs e) { // 首先确认当前地图文档是否有效 if (null != m_pageLayoutControl.DocumentFilename m_mapControl.CheckMxFile(m_pageLayoutControl.DocumentFilename)) { // 创建一个新的地图文档实例 IMapDocument mapDoc = new MapDocumentClass(); && // 打开当前地图文档 mapDoc.Open(m_pageLayoutControl.DocumentFilename, string.Empty); // 用 PageLayout 中的文档替换当前文档中的 PageLayout 部分 mapDoc.ReplaceContents((IMxdContents)m_pageLayoutControl.PageLayout); // 保存地图文档 mapDoc.Save(mapDoc.UsesRelativePaths, false); mapDoc.Close(); } } /// &summary& /// 另存为地图文档命令 /// &/summary& /// &param name=&sender&&&/param& /// &param name=&e&&&/param& private void SaveAs_Click(object sender, EventArgs e) { // 调用另存为命令 ICommand command = new ControlsSaveAsDocCommandClass(); command.OnCreate(m_controlsSynchronizer.ActiveControl); command.OnClick(); } /// &summary& /// 退出程序 /// &/summary& /// &param name=&sender&&&/param& /// &param name=&e&&&/param& private void Exit_Click(object sender, EventArgs e) { Application.Exit(); }3、 编译运行 按 F5 编译运行程序。 也许你会发现, 菜单命令的实现方式都是类型的。 没错, AE9.2 中, 在 内 置 了 许 多 常 用 的 Command 和 Tool , 如 ControlsAddDataCommandClass 、 ControlsMapZoomInToolClass 、 ControlsMapPanToolClass 等 等 , 这 些 内 置 对 象 在 ESRI.ArcGIS.Controls 命名空间中,你可以对象浏览器中查看。而且这些内置对象的调用方式 都类似,如下所示:// 定义 ICommand command = new ControlsSaveAsDocCommandClass(); // 创建 command.OnCreate(m_controlsSynchronizer.ActiveControl); // 调用 command.OnClick();希望你可以举一反三,去实现更多的你想要的功能。 第三讲 MapControl 与 PageLayoutControl 同 步摘要:在 ArcMap 中,能够很方面地进行 MapView 和 Layout View 两种视图的切换,而且二 者之间的数据是同步显示的。关于两种视图同步的实现方法有多种,可以使用 ObjectCopy 对象进行数据硬拷贝, 而比较简单的方法莫过于二者共享一份地图了, 这也是最常用的方法。 在 ArcMap 中,能够很方面地进行 MapView 和 Layout View 两种视图的切换,而且二者之间 的数据是同步显示的。 关于两种视图同步的实现方法有多种,可以使用 ObjectCopy 对象进行数据硬拷贝,而比较 简单的方法莫过于二者共享一份地图了,这也是最常用的方法。1、新建同步类 ControlsSynchronizer在解决方案面板中右击项目名,选择“添加|类” ,在类别中选择“Visual C#项目项” ,在模 板中选择“类” ,输入类名“ControlsSynchronizer.cs” ,将以下代码覆盖自动生成的代码:using S using System.D using System.C using System.ComponentM using System.Windows.F using System.IO; using System.Runtime.InteropS using ESRI.ArcGIS.esriS using ESRI.ArcGIS.C using ESRI.ArcGIS.C using ESRI.ArcGIS.SystemUI; namespace _sdnMap { /// &summary& /// This class is used to synchronize a gven PageLayoutControl and a MapControl. /// When initialized, the user must pass the reference of these control to the class, bind /// the control together by calling 'BindControls' which in turn sets a joined Map referenced /// and set all the buddy controls joined between these two controls. /// When alternating between the MapControl and PageLayoutControl, you should activate the visible control /// and deactivate the other by calling ActivateXXX. /// This calss is limited to a situation where the controls are not simultaneously visible. /// &/summary& public class ControlsSynchronizer { #region class members private IMapControl3 m_mapControl = private IPageLayoutControl2 m_pageLayoutControl = private ITool m_mapActiveTool = private ITool m_pageLayoutActiveTool = private bool m_IsMapCtrlactive = private ArrayList m_frameworkControls = #endregion #region constructor /// &summary& /// 默认构造函数 /// &/summary& public ControlsSynchronizer() { //初始化 ArrayList m_frameworkControls = new ArrayList(); } /// &summary& /// 构造函数 /// &/summary& /// &param name=&mapControl&&&/param& /// &param name=&pageLayoutControl&&&/param& public ControlsSynchronizer(IMapControl3 mapControl, pageLayoutControl) : this() { //为类成员赋值 m_mapControl = mapC m_pageLayoutControl = pageLayoutC } #endregion #region properties /// &summary& /// 取得或设置 MapControlIPageLayoutControl2 /// &/summary& public IMapControl3 MapControl { get { return m_mapC } set { m_mapControl = } } /// &summary& /// 取得或设置 PageLayoutControl /// &/summary& public IPageLayoutControl2 PageLayoutControl { get { return m_pageLayoutC } set { m_pageLayoutControl = } } /// &summary& /// 取得当前 ActiveView 的类型 /// &/summary& public string ActiveViewType { get { if (m_IsMapCtrlactive) return &MapControl&; else return &PageLayoutControl&; } } /// &summary& /// 取得当前活动的 Control /// &/summary& public object ActiveControl { get { if (m_mapControl == null || m_pageLayoutControl == null) throw new Exception(&ControlsSynchronizer::ActiveControl:\r\nEither MapControl or PageLayoutControl are not initialized!&); if (m_IsMapCtrlactive) return m_mapControl.O else return m_pageLayoutControl.O } } #endregion #region Methods /// &summary& /// 激活 MapControl 并解除 the PagleLayoutControl /// &/summary& public void ActivateMap() { try { if (m_pageLayoutControl == null || m_mapControl == null) throw new Exception(&ControlsSynchronizer::ActivateMap:\r\nEither MapControl or PageLayoutControl are not initialized!&); //缓存当前 PageLayout 的 CurrentTool if (m_pageLayoutControl.CurrentTool != null) m_pageLayoutActiveTool = m_pageLayoutControl.CurrentT //解除 PagleLayout m_pageLayoutControl.ActiveView.Deactivate(); //激活 MapControl m_mapControl.ActiveView.Activate(m_mapControl.hWnd); //将之前 MapControl 最后使用的 tool, 作为活动的 tool, 赋给 MapControl 的 CurrentTool if (m_mapActiveTool != null) m_mapControl.CurrentTool = m_mapActiveT m_IsMapCtrlactive = //为每一个的 framework controls,设置 Buddy control 为 MapControl this.SetBuddies(m_mapControl.Object); } catch (Exception ex) { throw Exception(string.Format(&ControlsSynchronizer::ActivateMap:\r\n{0}&, ex.Message)); } } /// &summary&new /// 激活 PagleLayoutControl 并减活 MapCotrol /// &/summary& public void ActivatePageLayout() { try { if (m_pageLayoutControl == null || m_mapControl == null) throw Exception(&ControlsSynchronizer::ActivatePageLayout:\r\nEither MapControl PageLayoutControl are not initialized!&); //缓存当前 MapControl 的 CurrentTool if (m_mapControl.CurrentTool != m_mapControl.CurrentT //解除 MapControl m_mapControl.ActiveView.Deactivate(); //激活 PageLayoutControl m_pageLayoutControl.ActiveView.Activate(m_pageLayoutControl.hWnd);new ornull)m_mapActiveTool=//将之前 PageLayoutControl 最后使用的 tool,作为活动的 tool,赋给 PageLayoutControl 的 CurrentTool if (m_pageLayoutActiveTool != null) m_pageLayoutControl.CurrentTool = m_pageLayoutActiveT m_IsMapCtrlactive = //为每一个的 framework controls,设置 Buddy control 为 PageLayoutControl this.SetBuddies(m_pageLayoutControl.Object); } catch (Exception ex) { throw new Exception(string.Format(&ControlsSynchronizer::ActivatePageLayout:\r\n{0}&, ex.Message)); } } /// &summary& /// 给予一个地图, 置换 PageLayoutControl 和 MapControl 的 focus map /// &/summary& /// &param name=&newMap&&&/param& public void ReplaceMap(IMap newMap) { if (newMap == null) throw new Exception(&ControlsSynchronizer::ReplaceMap:\r\nNew map for replacement is not initialized!&); if (m_pageLayoutControl == null || m_mapControl == null) throw new Exception(&ControlsSynchronizer::ReplaceMap:\r\nEither MapControl or PageLayoutControl are not initialized!&); //create a new instance of IMaps collection which is needed by the PageLayout //创建一个 PageLayout 需要用到的,新的 IMaps collection 的实例 IMaps maps = new Maps(); //add the new map to the Maps collection //把新的地图加到 Maps collection 里头去 maps.Add(newMap); bool bIsMapActive = m_IsMapC //call replace map on the PageLayout in order to replace the focus map //we must call ActivatePageLayout, since it is the control we call 'ReplaceMaps' //调用 PageLayout 的 replace map 来置换 focus map //我们必须调用 ActivatePageLayout,因为它是那个我们可以调用&ReplaceMaps& 的 Control this.ActivatePageLayout(); m_pageLayoutControl.PageLayout.ReplaceMaps(maps); //assign the new map to the MapControl //把新的地图赋给 MapControl m_mapControl.Map = newM //reset the active tools //重设 active tools m_pageLayoutActiveTool = m_mapActiveTool = //make sure that the last active control is activated //确认之前活动的 control 被激活 if (bIsMapActive) { this.ActivateMap(); m_mapControl.ActiveView.Refresh(); } else { this.ActivatePageLayout(); m_pageLayoutControl.ActiveView.Refresh(); } } /// &summary& /// bind the MapControl and PageLayoutControl together by assigning a new joint focus map /// 指定共同的 Map 来把 MapControl 和 PageLayoutControl 绑在一起 /// &/summary& /// &param name=&mapControl&&&/param& /// &param name=&pageLayoutControl&&&/param& /// &param name=&activateMapFirst&&true if the MapControl supposed to be activated first,如果 MapControl 被首先激活,则为 true&/param& public void BindControls(IMapControl3 mapControl, IPageLayoutControl2 pageLayoutControl, bool activateMapFirst) { if (mapControl == null || pageLayoutControl == null) throw new Exception(&ControlsSynchronizer::BindControls:\r\nEither MapControl or PageLayoutControl are not initialized!&); m_mapControl = MapC m_pageLayoutControl = pageLayoutC this.BindControls(activateMapFirst); } /// &summary& /// bind the MapControl and PageLayoutControl together by assigning a new joint focus map /// 指定共同的 Map 来把 MapControl 和 PageLayoutControl 绑在一起 /// &/summary& /// &param name=&activateMapFirst&&true if the MapControl supposed to be activated first,如果 MapControl 被首先激活,则为 true&/param& public void BindControls(bool activateMapFirst) { if (m_pageLayoutControl == null || m_mapControl == null) throw new Exception(&ControlsSynchronizer::BindControls:\r\nEither MapControl or PageLayoutControl are not initialized!&); //create a new instance of IMap //创造 IMap 的一个实例 IMap newMap = new MapClass(); newMap.Name = &Map&; //create a new instance of IMaps collection which is needed by the PageLayout //创造一个新的 IMaps collection 的实例,这是 PageLayout 所需要的 IMaps maps = new Maps(); //add the new Map instance to the Maps collection //把新的 Map 实例赋给 Maps collection maps.Add(newMap); //call replace map on the PageLayout in order to replace the focus map //调用 PageLayout 的 replace map 来置换 focus map m_pageLayoutControl.PageLayout.ReplaceMaps(maps); //assign the new map to the MapControl //把新的 map 赋给 MapControl m_mapControl.Map = newM //reset the active tools //重设 active tools m_pageLayoutActiveTool = m_mapActiveTool = //make sure that the last active control is activated //确定最后活动的 control 被激活 if (activateMapFirst) this.ActivateMap(); else this.ActivatePageLayout(); } /// &summary& ///by passing the application's toolbars and TOC to the synchronization class, it saves you the ///management of the buddy control each time the active control changes. This method ads the framework /// once the active control changes, the class iterates through the array and ///calles SetBuddyControl on each of the stored framework control. /// &/summary& /// &param name=&control&&&/param& public void AddFrameworkControl(object control) { if (control == null) throw new Exception(&ControlsSynchronizer::AddFrameworkControl:\r\nAdded control is not initialized!&); m_frameworkControls.Add(control); } /// &summary& /// Remove a framework control from the managed list of controls /// &/summary& /// &param name=&control&&&/param& public void RemoveFrameworkControl(object control) { if (control == null) throw new Exception(&ControlsSynchronizer::RemoveFrameworkControl:\r\nControl to be removed is not initialized!&); m_frameworkControls.Remove(control); } /// &summary& /// Remove a framework control from the managed list of controls by specifying its index in the list /// &/summary& /// &param name=&index&&&/param& public void RemoveFrameworkControlAt(int index) { if (m_frameworkControls.Count & index) throw new Exception(&ControlsSynchronizer::RemoveFrameworkControlAt:\r\nIndex is out of range!&); m_frameworkControls.RemoveAt(index); } /// &summary& /// when the active control changes, the class iterates through the array of the framework controls /// and calles SetBuddyControl on each of the controls. /// &/summary& /// &param name=&buddy&&the active control&/param& private void SetBuddies(object buddy) { try { if (buddy == null) throw new Exception(&ControlsSynchronizer::SetBuddies:\r\nTarget Buddy Control is not initialized!&); foreach (object obj in m_frameworkControls) { if (obj is IToolbarControl) { ((IToolbarControl)obj).SetBuddyControl(buddy); } else if (obj is ITOCControl) { ((ITOCControl)obj).SetBuddyControl(buddy); } } } catch (Exception ex) { throw Exception(string.Format(&ControlsSynchronizer::SetBuddies:\r\n{0}&, ex.Message)); } } #endregion } } 2、新建 Maps 类 在同步类中, 要用到 Maps 类, 用于管理地图对象。 与新建同步类 ControlsSynchronizer 类似, 我们新建一 Maps 类,其所有代码如下所示:newusing S using System.C using System.Collections.G using System.T using System.Runtime.InteropS using ESRI.ArcGIS.C namespace _sdnMap { [Guid(&f27d8789-fbbc-4801-be78-0e3cd8fff9d5&)] [ClassInterface(ClassInterfaceType.None)] [ProgId(&_sdnMap.Maps&)] public class Maps : IMaps, IDisposable { //class member - using internally an ArrayList to manage the Maps collection private ArrayList m_array = #region class constructor public Maps() { m_array = new ArrayList(); } #endregion #region IDisposable Members /// &summary& /// Dispose the collection /// &/summary& public void Dispose() { if (m_array != null) { m_array.Clear(); m_array = } } #endregion #region IMaps Members /// &summary& /// Remove the Map at the given index /// &/summary& /// &param name=&Index&&&/param& public void RemoveAt(int Index) { if (Index & m_array.Count || Index & 0) throw new Exception(&Maps::RemoveAt:\r\nIndex is out of range!&); m_array.RemoveAt(Index); } /// &summary& /// Reset the Maps array /// &/summary& public void Reset() { m_array.Clear(); } /// &summary& /// Get the number of Maps in the collection /// &/summary& public int Count { get { return m_array.C } } /// &summary& /// Return the Map at the given index /// &/summary& /// &param name=&Index&&&/param& /// &returns&&/returns& public IMap get_Item(int Index) { if (Index & m_array.Count || Index & 0) throw new Exception(&Maps::get_Item:\r\nIndex is out of range!&); return m_array[Index] as IM } /// &summary& /// Remove the instance of the given Map /// &/summary& /// &param name=&Map&&&/param& public void Remove(IMap Map) { m_array.Remove(Map); } /// &summary& /// Create a new Map, add it to the collection and return it to the caller /// &/summary& /// &returns&&/returns& public IMap Create() { IMap newMap = new MapClass(); m_array.Add(newMap); return newM } /// &summary& /// Add the given Map to the collection /// &/summary& /// &param name=&Map&&&/param& public void Add(IMap Map) { if (Map == null) throw new Exception(&Maps::Add:\r\nNew Map is mot initialized!&); m_array.Add(Map); } #endregion } }3、新建打开文档类 OpenNewMapDocument由于从工具栏自带的打开按钮打开地图文档的时候, 不会自动进行两种视图之间的同步, 所 以我们要自己派生一个 OpenNewMapDocument 类,用于打开地图文档。 右击项目名,选择“添加|类” ,再选择 ArcGIS 类别中的 BaseCommand 模板,输入类名为 “OpenNewMapDocument.cs” 。 首先添加引用:using System.Windows.F using ESRI.ArcGIS.C再添加如下成员变量:private ControlsSynchronizer m_controlsSynchronizer = 修改默认的构造函数如下所示://添加参数 public OpenNewMapDocument(ControlsSynchronizer controlsSynchronizer) { // // TODO: Define values for the public properties // //设定相关属性值 base.m_category = &Generic&; //localizable text base.m_caption = &Open&; //localizable text base.m_message = &This should work in ArcMap/MapControl/PageLayoutControl&; //localizable text base.m_toolTip = &Open&; //localizable text base.m_name = &Generic_Open&; //unique id, non-localizable (e.g. &MyCategory_MyCommand&) //初始化 m_controlsSynchronizer m_controlsSynchronizer = controlsS try { // // TODO: change bitmap name if necessary // string bitmapResourceName = GetType().Name + &.bmp&; base.m_bitmap = new Bitmap(GetType(), bitmapResourceName); } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.Message, &Invalid Bitmap&); } }再在 OnClick 函数中添加如下代码:public override void OnClick() { // TODO: Add OpenNewMapDocument.OnClick implementation OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = &Map Documents (*.mxd)|*.mxd&; dlg.Multiselect = dlg.Title = &Open Map Document&; if (dlg.ShowDialog() == DialogResult.OK) { string docName = dlg.FileN IMapDocument mapDoc = new MapDocumentClass(); if (mapDoc.get_IsPresent(docName) && !mapDoc.get_IsPasswordProtected(docName)) { mapDoc.Open(docName, string.Empty); IMap map = mapDoc.get_Map(0); m_controlsSynchronizer.ReplaceMap(map); mapDoc.Close(); } } }在添加类时,模板会自动添加一个名为“OpenNewMapDocument.bmp”的图标,你可以自 己修改或者替换为打开的文件夹的图标。 4、两种视图的同步在 3sdnMap.cs 中添加成员变量,即同步类对象:private ControlsSynchronizer m_controlsSynchronizer =在 Form1_Load 函数中进行初始化工作://初始化 controls synchronization calss m_controlsSynchronizer = new ControlsSynchronizer(m_mapControl, m_pageLayoutControl); //把 MapControl 和 PageLayoutControl 绑定起来(两个都指向同一个 Map),然后设置 MapControl 为活动的 Control m_controlsSynchronizer.BindControls(true); //为了在切换 MapControl 和 PageLayoutControl 视图同步,要添加 Framework Control m_controlsSynchronizer.AddFrameworkControl(axToolbarControl1.Object); m_controlsSynchronizer.AddFrameworkControl(this.axTOCControl1.Object); // 添加打开命令按钮到工具条 OpenNewMapDocument openMapDoc OpenNewMapDocument(m_controlsSynchronizer); axToolbarControl1.AddItem(openMapDoc, -1, esriCommandStyles.esriCommandStyleIconOnly);= 0, false,new -1,因为我们自动派生了打开文档类, 并自己将其添加到工具条, 所以我们就不需要工具条原来 的“打开”按钮了,可以 ToolbarControl 的属性中将其删除。 下面,我们可完成上一讲遗留的功能了。/// &summary& /// 新建地图命令 /// &/summary& /// &param name=&sender&&&/param& /// &param name=&e&&&/param& private void New_Click(object sender, EventArgs e) { //询问是否保存当前地图 DialogResult res = MessageBox.Show(& 是 否 保 存 当 前 地 图 ?&, & 提 示 &, MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (res == DialogResult.Yes) { //如果要保存,调用另存为对话框 ICommand command = new ControlsSaveAsDocCommandClass(); if (m_mapControl != null) command.OnCreate(m_controlsSynchronizer.MapControl.Object); else command.OnCreate(m_controlsSynchronizer.PageLayoutControl.Object); command.OnClick(); } //创建新的地图实例 IMap map = new MapClass(); map.Name = &Map&; m_controlsSynchronizer.MapControl.DocumentFilename = string.E //更新新建地图实例的共享地图文档 m_controlsSynchronizer.ReplaceMap(map); } /// &summary& /// 打开地图文档 Mxd 命令 /// &/summary& /// &param name=&sender&&&/param& /// &param name=&e&&&/param& private void Open_Click(object sender, EventArgs e) { if (this.axMapControl1.LayerCount & 0) { DialogResult result = MessageBox.Show(&是否保存当前地图?&, &警告&, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (result == DialogResult.Cancel) if (result == DialogResult.Yes) this.Save_Click(null, null); } OpenNewMapDocument openMapDoc = new OpenNewMapDocument(m_controlsSynchronizer); openMapDoc.OnCreate(m_controlsSynchronizer.MapControl.Object); openMapDoc.OnClick(); }在添加数据 AddData 时,我们也要进行地图共享,故在 AddData_Click 函数后面添加如下代 码:IMap pMap = this.axMapControl1.M this.m_controlsSynchronizer.ReplaceMap(pMap);在另存为地图文档时,有可能会丢失数据,因此我们需要提示用户以确认操作,故需修改 SaveAs_Click 函数,如下所示:/// &summary& /// 另存为地图文档命令 /// &/summary& /// &param name=&sender&&&/param& /// &param name=&e&&&/param& private void SaveAs_Click(object sender, EventArgs e) { // 如 果 当 前 视 图 为 MapControl 时 , 提 示 用 户 另 存 为 操 作 将 丢 失 PageLayoutControl 中的设置 if (m_controlsSynchronizer.ActiveControl is IMapControl3) { if (MessageBox.Show(&另存为地图文档将丢失制版视图的设置\r\n 您要继 续吗?&, &提示&, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) } //调用另存为命令 ICommand command = new ControlsSaveAsDocCommandClass(); command.OnCreate(m_controlsSynchronizer.ActiveControl); command.OnClick(); }在切换视图时,我们要激活相关的视图,故在设计视图的属性面板中选择 tabControl2 控件, 再选择事件按钮,找到“SelectedIndexChanged”事件双击添加之。其实现代码如下所示:/// &summary& /// 切换地图和制版视图 /// &/summary& /// &param name=&sender&&&/param& /// &param name=&e&&&/param& private void tabControl2_SelectedIndexChanged(object sender, EventArgs e) { if (this.tabControl2.SelectedIndex == 0) { //激活 MapControl m_controlsSynchronizer.ActivateMap(); } else { //激活 PageLayoutControl m_controlsSynchronizer.ActivatePageLayout(); } }5、编译运行 按 F5 编译运行程序, 至此我们完成了 MapControl 和 PageLayoutControl 两种视图的同步工作。第四讲 状态栏信息的添加与实现摘要:在上一讲中,我们完成了 MapControl 和 PageLayoutControl 两种视图的同步工作, 本讲我们将完成状态栏信息的添加与实现。应用程序的状态栏一般用来显示程序的当前状 态,当前所使用的工具。 GIS 应用程序一般也在状态栏显示当前光标的坐标、比例尺等信 息。学习完本讲内容,您将学会状态栏编程的基本方法,并且能够在我们的程序的状态栏中 添加且显示以下信息:当前所用工具信息、当前比例尺、当前坐标。 在上一讲中,我们完成了 MapControl 和 PageLayoutControl 两种视图的同步工作,本讲我 们将完成状态栏信息的添加与实现。 应用程序的状态栏一般用来显示程序的当前状态,当前所使用的工具。 GIS 应用程序一般 也在状态栏显示当前光标的坐标、比例尺等信息。 学习完本讲内容, 您将学会状态栏编程的基本方法, 并且能够在我们的程序的状态栏中添加 且显示以下信息: 当前所用工具信息 当前比例尺 当前坐标1、 添加状态栏项目在设计视图中,点击窗体中的状态栏,在其属性面板中找到“ Items ”项,单击其右边的 按钮,在下拉框中选择“ StatusLabel ” ,单击“添加按钮” ,依次添加四个 StatusLabel , 依次修改属性参数如下表所示: 序号 1 2 3 4 Name 属性 MessageLabel Blank ScaleLabel CoordinateLabel 比例尺 当前坐标 Text 属性 就绪 Spring 属性 False True False False 说明 当前所用工具信息 占位 当前比例尺 当前坐标设置好之后如下图所示: Tips : 我们设计出的状态栏最终如下所示: 就绪 ( Blank ) 比例尺 当前坐标Spring 属性表示可以按状态栏剩余空间自动伸缩。所以加入 Blank 项目,只是为了占个位 子,以达到 ScaleLabel 和 CoordinateLabel 项目右对齐而 MessageLabel 项目左对齐的目 的。2、 显示当前所用工具信息首先添加 axToolbarControl1 的 OnMouseMove 事件 ( 相信大家看了以上的教程, 已经知道 怎么添加事件了吧,还不知道的建议再温习下前几讲的内容 ) 。在其事件响应函数代码如 下: private void axToolbarControl1_OnMouseMove(object sender, IToolbarControlEvents_OnMouseMoveEvent e) { // 取得鼠标所在工具的索引号 int index = axToolbarControl1.HitTest(e.x, e.y, false); if (index != -1) { // 取得鼠标所在工具的 ToolbarItem IToolbarItem toolbarItem = axToolbarControl1.GetItem(index); // 设置状态栏信息 MessageLabel.Text = toolbarItem.Command.M } else { MessageLabel.Text = & 就绪 &; } }3、 显示当前比例尺添加 axMapControl1 的 OnMouseMove 事件,其代码如下:private void axMapControl1_OnMouseMove(object IMapControlEvents2_OnMouseMoveEvent e) { // 显示当前比例尺 ScaleLabel.Text = & 比例尺 1:& + ((long)this.axMapControl1.MapScale).ToString(); }sender, 4、 显示当前坐标显 示 当 前 坐 标 也 是 axMapControl1 的 OnMouseMove 事 件 中 响 应 , 故 只 要 在 axMapControl1_OnMouseMove 函数中添加如下代码即可:// 显示当前坐标 CoordinateLabel.Text = & 当前坐标 X = & + e.mapX.ToString() + & Y = & + e.mapY.ToString() + & & + this.axMapControl1.MapU 按 F5 编译运行,可以看到,我们的程序已经能够正常工作了。但是细心的你可能会发现, 当前坐标的后面的坐标单位为“ esriUnknownUnits ”或“ esriMeters ”之类,即系统在正 常单位的前面加上了“ esri ” ,追求完美的我们自然看得不舒服。那就进行简单的替换吧。 首先定义个全局坐标单位变量 sMapUnits ,如下所示:private string sMapU再 Form1_Load 函数中进行初始化:sMapUnits = &Unknown&;添加 axMapControl1 控件的 OnMapReplaced 事件,在事件响应函数中进行坐标单位替换, 代码如下:private void axMapControl1_OnMapReplaced(object IMapControlEvents2_OnMapReplacedEvent e) { esriUnits mapUnits = axMapControl1.MapU switch (mapUnits) { case esriUnits.esriCentimeters:sender, sMapUnits = &Centimeters&; case esriUnits.esriDecimalDegrees: sMapUnits = &Decimal Degrees&; case esriUnits.esriDecimeters: sMapUnits = &Decimeters&; case esriUnits.esriFeet: sMapUnits = &Feet&; case esriUnits.esriInches: sMapUnits = &Inches&; case esriUnits.esriKilometers: sMapUnits = &Kilometers&; case esriUnits.esriMeters: sMapUnits = &Meters&; case esriUnits.esriMiles: sMapUnits = &Miles&;
case esriUnits.esriMillimeters: sMapUnits = &Millimeters&; case esriUnits.esriNauticalMiles: sMapUnits = &NauticalMiles&; case esriUnits.esriPoints: sMapUnits = &Points&; case esriUnits.esriUnknownUnits: sMapUnits = &Unknown&; case esriUnits.esriYards: sMapUnits = &Yards&; } }5、 编译运行按 F5 编译运行程序。如果你足够细心的话,相信你已经成功了! 在本讲中,介绍中 StatusStrip 控件的基本使用方法和 AE 中当所用工具信息、当前比例尺 和当前坐标的显示调用方法。 第五讲 鹰眼的实现摘要:所谓的鹰眼,就是一个缩略地图,上面有一个矩形框,矩形框区域就是当前显示的地 图区域,拖动矩形框可以改变当前地图显示的位置,改变矩形框的大小,可以改变当前地图 的显示区域大小,从起到导航的作用。鹰眼是地图浏览中常用的功能之一。关于鹰眼的实现 方式,最常用的是用一个 MapControl 控件显示地图全图,并在上面画一个红色矩形框表示 当前地图的显示范围,并实现鹰眼 MapControl 与主窗体的 MapControl 互动。 在上一讲中,我们实现了状态栏的相关信息显示,在这一讲中我们将要实现鹰眼功能。 所谓的鹰眼, 就是一个缩略地图, 上面有一个矩形框, 矩形框区域就是当前显示的地图区域, 拖动矩形框可以改变当前地图显示的位置, 改变矩形框的大小, 可以改变当前地图的显示区 域大小,从起到导航的作用。鹰眼是地图浏览中常用的功能之一。 关于鹰眼的实现方式,最常用的是用一个 MapControl 控件显示地图全图,并在上面画一个 红色矩形框表示当前地图的显示范围,并实现鹰眼 MapControl 与主窗体的 MapControl 互 动。本讲最终效果如下所示:图 1 鹰眼效果 1 、添加鹰眼控件由于本教程在第一讲中没有预先考虑到鹰眼所放的位置,故我们要先稍微调整一下程序框 架,并添加一个 MapControl 用于显示鹰眼。 在本教程中,我们将鹰眼放在图层控件的下方,调整方法如下: ( 1 ) 在设计视图中, 选择 tabControl1 控件, 即放图层和属性的那个容器, 将其 Dock 属 性设为 None , 并用鼠标拖拽将其缩小。 把工具箱中的 SplitContainer 控件拖到窗体的左窗 格,即放在 tabControl1 控件的旁边。并将其 Orientation 属性设置为 Horizontal 。 ( 2 )选中 tabControl1 控件,按 Ctrl+X 剪切,再选中刚才粘贴到 SplitContainer2 的 Panel1 中,如图 2 所示。操作完成后效果如图 3 所示。 图 2图 3 ( 3 ) 再 选 中 SplitContainer2 控 件 ( 如 果 不 好 选 中 , 直 接 以 属 性 面 板 中 选 择 SplitContainer2 ) ,将其 Dock 属性设置为 Fill 。再选中 tabControl1 ,将其 Dock 属性也 设置为 Fill 。 ( 4 )从工具箱中选择 MapControl 控件并拖到 SplitContainer2 的 Panel2 ,作为鹰眼控 件。最终效果如图 4 所示。 图 42 、鹰眼的实现( 1 )载入地图到鹰眼控件 当地图载入到主 Map 控件时,同时也载入到鹰眼控件,在 axMapControl1_OnMapReplaced 事件响应函数(此函数上一讲中已经添加了)中添加如下代码: private void axMapControl1_OnMapReplaced(object IMapControlEvents2_OnMapReplacedEvent e) { // 前面代码省略 // 当主地图显示控件的地图更换时,鹰眼中的地图也跟随更换 this.axMapControl2.Map = new MapClass(); sender, // 添加主地图控件中的所有图层到鹰眼控件中 for (int i = 1; i &= this.axMapControl1.LayerC i++) { this.axMapControl2.AddLayer(this.axMapControl1.get_Layer(this.axMapControl1.LayerCount i)); } // 设置 MapControl 显示范围至数据的全局范围 this.axMapControl2.Extent = this.axMapControl1.FullE // 刷新鹰眼控件地图 this.axMapControl2.Refresh(); } ( 2 )绘制鹰眼矩形框 为鹰眼控件 MapControl1 添加 OnExtentUpdated 事件,此事件是在主 Map 控件的显示范 围改变时响应,从而相应更新鹰眼控件中的矩形框。其响应函数代码如下: private void axMapControl1_OnExtentUpdated(object IMapControlEvents2_OnExtentUpdatedEvent e) { // 得到新范围 IEnvelope pEnv = (IEnvelope)e.newE IGraphicsContainer pGra = axMapControl2.Map as IGraphicsC IActiveView pAv = pGra as IActiveV // 在绘制前,清除 axMapControl2 中的任何图形元素 pGra.DeleteAllElements(); sender, - IRectangleElement pRectangleEle = new RectangleElementClass(); IElement pEle = pRectangleEle as IE pEle.Geometry = pE // 设置鹰眼图中的红线框 IRgbColor pColor = new RgbColorClass(); pColor.Red = 255; pColor.Green = 0; pColor.Blue = 0; pColor.Transparency = 255; // 产生一个线符号对象 ILineSymbol pOutline = new SimpleLineSymbolClass(); pOutline.Width = 2; pOutline.Color = pC // 设置颜色属性 pColor = new RgbColorClass(); pColor.Red = 255; pColor.Green = 0; pColor.Blue = 0; pColor.Transparency = 0; // 设置填充符号的属性 IFillSymbol pFillSymbol = new SimpleFillSymbolClass(); pFillSymbol.Color = pC pFillSymbol.Outline = pO IFillShapeElement pFillShapeEle = pEle as IFillShapeE pFillShapeEle.Symbol = pFillS pGra.AddElement((IElement)pFillShapeEle, 0); // 刷新 pAv.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); } ( 3 )鹰眼与主 Map 控件互动 为鹰眼控件 MapControl2 添加 OnMouseDown 事件,代码如下: private void axMapControl2_OnMouseDown(object IMapControlEvents2_OnMouseDownEvent e) { if (this.axMapControl2.Map.LayerCount != 0) { // 按下鼠标左键移动矩形框 if (e.button == 1) { IPoint pPoint = new PointClass(); pPoint.PutCoords(e.mapX, e.mapY); IEnvelope pEnvelope = this.axMapControl1.E pEnvelope.CenterAt(pPoint); this.axMapControl1.Extent = pE this.axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, sender, null); } // 按下鼠标右键绘制矩形框 else if (e.button == 2) { IEnvelope pEnvelop = this.axMapControl2.TrackRectangle(); this.axMapControl1.Extent = pE this.axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null); } } } 为鹰眼控件 MapControl2 添加 OnMouseMove 事件,主要实现按下鼠标左键的时候移动矩 形框,同时也改变主的图控件的显示范围。代码如下: private void axMapControl2_OnMouseMove(object IMapControlEvents2_OnMouseMoveEvent e) { // 如果不是左键按下就直接返回 if (e.button != 1) IPoint pPoint = new PointClass(); pPoint.PutCoords(e.mapX, e.mapY); this.axMapControl1.CenterAt(pPoint); this.axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null); null, sender, null, }3、 编译运行按 F5 编译运行程序。 期待的鹰眼功能你已经实现了, 按下左键在鹰眼窗口中移动, 或者按下右键在鹰眼窗口中画 一个矩形, 主地图窗口的显示范围都会跟着变化。 主地图窗口中的地图经放大缩小等操作后, 鹰眼窗口的矩形框大小也会随着改变。第六讲 右键菜单添加与实现摘要:在这一讲中,大家将实现 TOCControl 控件和主地图控件的右键菜单。在 AE 开发中, 右键菜单有两种实现方式,一是使用 VS2005 自带的 ContextMenuStrip 控件,二是用 AE 封 装的 IToolbarMenu 接口。相比较而言,后者更为简单实用,本文采用后者的实现方法。 在上一讲中,我们完成了鹰眼功能,在这一讲中,大家将实现 TOCControl 控件和主地图控 件的右键菜单。在 AE 开发中,右键菜单有两种实现方式,一是使用 VS2005 自带的 ContextMenuStrip 控件, 二是用 AE 封装的 IToolbarMenu 接口。相比较而言,后者更为简单实用,本文采用后者的实 现方法。1、创建右键菜单在 Form1 类里面添加如下变量的定义://TOCControl 控件变量 private ITOCControl2 m_tocControl = //TOCControl 中 Map 菜单 private IToolbarMenu m_menuMap = //TOCControl 中图层菜单 private IToolbarMenu m_menuLayer = 在 Form1_Load 函数进行初始化,即菜单的创建: m_menuMap = new ToolbarMenuClass(); m_menuLayer = new ToolbarMenuClass();2、添加菜单项第 1 步中创建的菜单可认为是菜单容器, 里面什么都没有, 具体的命令或工具作为菜单项添 加到菜单容器才能工作。一般情况下,启动程序就要完成菜单项的添加,故此工作在 Form1_Load 函数完成。 当然,添加菜单项之前,必须实现相应命令或工具。这里的命令或工具可以 AE 内置的也可 以 是 自 定 义 的 。 AE 内 置 了 许 多 可 以 直 接 调 用 的 常 用 命 令 和 工 具 , 如 ControlsAddDataCommandClass,在 ESRI.ArcGIS.Controls 命名空间中,大家可以对象浏览器中 查看。当然,这里也可以直接调用 AE 内置的菜单,如 ControlsFeatureSelectionMenu。另外, 本讲也实现三自定义命令,以做示范。它们分别为图层可视控制命令(用于控制图层显示与 否) 、移除图层和放大到整个图层命令。实现方法也很简单,就是右击 3sdnMap 项目,选择 “添加|类” ,选择 C#普通的类模板,用以下代码覆盖系统自己生成的所有代码。 图层可视控制类 LayerVisibility 代码:using ESRI.ArcGIS.ADF.BaseC using ESRI.ArcGIS.C using ESRI.ArcGIS.C using ESRI.ArcGIS.SystemUI;namespace _sdnMap { /// &summary& /// 图层可视控制 /// &/summary& public sealed class LayerVisibility : BaseCommand, ICommandSubType { private IHookHelper m_hookHelper = new HookHelperClass(); private long m_subTpublic LayerVisibility() { }public override void OnClick() { for (int i=0; i &= m_hookHelper.FocusMap.LayerCount - 1; i++) { if (m_subType m_hookHelper.FocusMap.get_Layer(i).Visible = if (m_subType m_hookHelper.FocusMap.get_Layer(i).Visible = } == 1)==2)m_hookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography,null,null); } public override void OnCreate(object hook) { m_hookHelper.Hook = }public int GetCount() { return 2; }public void SetSubType(int SubType) { m_subType = SubT }public override string Caption { get { if (m_subType == 1) return &Turn All Layers On&; else return &Turn All Layers Off&; } }public override bool Enabled { get { bool enabled = if (m_subType == 1) { for 1;i++) { if (m_hookHelper.ActiveView.FocusMap.get_Layer(i).Visible == false) { enabled = } } } else { for (i=0;i&=m_hookHelper.FocusMap.LayerCount (i=0;i&=m_hookHelper.FocusMap.LayerCount - 1;i++) { if (m_hookHelper.ActiveView.FocusMap.get_Layer(i).Visible == true) { enabled = } } } } } } }移除图层类 RemoveLayer 代码:using ESRI.ArcGIS.ADF.BaseC using ESRI.ArcGIS.C using ESRI.ArcGIS.Cnamespace _sdnMap { /// &summary& /// 删除图层 /// &/summary& public sealed class RemoveLayer : BaseCommand { private IMapControl3 m_mapCpublic RemoveLayer() { base.m_caption = &Remove Layer&; }public override void OnClick() { ILayer layer = (ILayer)m_mapControl.CustomP m_mapControl.Map.DeleteLayer(layer); }public override void OnCreate(object hook) { m_mapControl = (IMapControl3) } } } 放大至整个图层类 ZoomToLayer:using ESRI.ArcGIS.ADF.BaseC using ESRI.ArcGIS.C using ESRI.ArcGIS.Cnamespace _sdnMap { /// &summary& /// 放大至整个图层 /// &/summary& public sealed class ZoomToLayer : BaseCommand { private IMapControl3 m_mapCpublic ZoomToLayer() { base.m_caption = &Zoom To Layer&; } public override void OnClick() { ILayer layer = (ILayer)m_mapControl.CustomP m_mapControl.Extent = layer.AreaOfI }public override void OnCreate(object hook) { m_mapControl = (IMapControl3) } } } 以上三个工具或命令的实现代码比较简单,在此不过多的分析,请读者自行理解。 下面在 Form1_Load 函数中进行菜单项的添加,代码如下://添加自定义菜单项到 TOCCOntrol 的 Map 菜单中 //打开文档菜单 m_menuMap.AddItem(new OpenNewMapDocument(m_controlsSynchronizer), -1, 0, false, esriCommandStyles.esriCommandStyleIconAndText); //添加数据菜单 m_menuMap.AddItem(new ControlsAddDataCommandClass(), esriCommandStyles.esriCommandStyleIconAndText); //打开全部图层菜单 m_menuMap.AddItem(new LayerVisibility(), 1, 2, false, -1, 1, false, esriCommandStyles.esriCommandStyleTextOnly); //关闭全部图层菜单 m_menuMap.AddItem(new LayerVisibility(), esriCommandStyles.esriCommandStyleTextOnly); //以二级菜单的形式添加内置的“选择”菜单 m_menuMap.AddSubMenu(&esriControls.ControlsFeatureSelectionMenu&, 4, true); //以二级菜单的形式添加内置的“地图浏览”菜单 m_menuMap.AddSubMenu(&esriControls.ControlsMapViewMenu&,5, true); 2, 3, false,//添加自定义菜单项到 TOCCOntrol 的图层菜单中 m_menuLayer = new ToolbarMenuClass(); //添加“移除图层”菜单项 m_menuLayer.AddItem(new RemoveLayer(), esriCommandStyles.esriCommandStyleTextOnly); //添加“放大到整个图层”菜单项 m_menuLayer.AddItem(new ZoomToLayer(), esriCommandStyles.esriCommandStyleTextOnly); -1, 1, true, -1, 0, false,//设置菜单的 Hook m_menuLayer.SetHook(m_mapControl); m_menuMap.SetHook(m_mapControl); 3、弹出右键菜单顾名思义,右键菜单是在鼠标右键按下的时候弹出,所以我们要添加 TOCControl1 控件的 OnMouseDown 事件,实现代码如下:private void axTOCControl1_OnMouseDown(object ITOCControlEvents_OnMouseDownEvent e) { //如果不是右键按下直接返回 if (e.button != 2)sender,esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemN IBasicMap map = ILayer layer = object other = object index =//判断所选菜单的类型 m_tocControl.HitTest(e.x, e.y, ref item, ref map, ref layer, ref other, ref index);//确定选定的菜单类型,Map 或是图层菜单 if (item == esriTOCControlItem.esriTOCControlItemMap) m_tocControl.SelectItem(map, null); else m_tocControl.SelectItem(layer, null);//设置 CustomProperty 为 layer (用于自定义的 Layer 命令) m_mapControl.CustomProperty =//弹出右键菜单 if (item == esriTOCControlItem.esriTOCControlItemMap) m_menuMap.PopupMenu(e.x, e.y, m_tocControl.hWnd); if (item == esriTOCControlItem.esriTOCControlItemLayer) m_menuLayer.PopupMenu(e.x, e.y, m_tocControl.hWnd); }同样的方法,我们也可以实现主地图控件的右键菜单,以方便地图浏览。添加 MapControl1 控件的 OnMouseDown 事件,实现代码如下:/// &summary& /// 主地图控件的右键响应函数 /// &/summary& /// &param name=&sender&&&/param& /// &param name=&e&&&/param& private void axMapControl1_OnMouseDown(object IMapControlEvents2_OnMouseDownEvent e) { sender, if (e.button == 2) { //弹出右键菜单 m_menuMap.PopupMenu(e.x,e.y,m_mapControl.hWnd); } }4、编译运行按 F5 编译运行程序,你会发现,原来右键菜单实现起来是这么的简单啊! 到第六讲为止已经发现的教程 Bug 及解决方法如下: 1、在第二讲可能会出现变量未定义。 原因:第二讲与第三讲联系紧密,我为控制篇幅才将其分为两讲,某些变量是在第三讲才进 行定义,请大家注意。 2、第六讲弹不出 TOCControl 的右键菜单 原因:没有取得 m_tocControl 的指针,即没有把 m_tocControl 指针与 axTOCControl1 控件绑 定,导致调用 m_menuMap.PopupMenu(e.x, e.y, m_tocControl.hWnd);时 m_tocControl.hWnd 为 NULL,故无法弹出菜单。 解决方法:在 Form1_Load()函数中,添加如下代码:m_tocControl = (ITOCControl2)this.axTOCControl1.O目前已经发现的优化方案如下: 1、 教程第四讲, 坐标单位前面的 esri, 原用 switch 语句逐一替换, 其实直接用取子串(Substring) 的方法截去更方便。 修改代码如下:CoordinateLabel.Text = & 当前坐标 X = & + e.mapX.ToString() + & Y = & + e.mapY.ToString() + & & + this.axMapControl1.MapUnits.ToString().Substring(4); 2、教程第四讲,固定状态栏中的比例尺和当前坐标项目的宽度以防止闪烁。 方法如下: 选中状态栏中的比例尺或当前坐标项目,把其 autoSize 属性设为 False,再在 Size 属性里设 置宽度。经测试,比例尺宽度为 150,当前坐标宽度为 400 比较合适。第七讲 图层符号选择器的实现 1摘要:我们要实现的是图层符号选择器,与 ArcMap 中的 Symbol Selector 的类似。本讲较前 几讲而言,些许有些复杂,不过只要仔细琢磨,认真操作,你就很容易实现如下所示的符号 选择器。 在上一讲中,我们实现了右键菜单(ContextMenu)的添加与实现,在最后我预留给下一讲 的问题是 TOCControl 控件图层拖拽的实现。后来发现此功能的实现异常简单,只要在 TOCControl 的属性页中,勾选“Enable Layer Drag and Drop”即可。 这一讲,我们要实现的是图层符号选择器,与 ArcMap 中的 Symbol Selector 的类似。本讲较 前几讲而言,些许有些复杂,不过只要仔细琢磨,认真操作,你就很容易实现如下所示的符 号选择器。因为本讲篇幅较长,故我将其分成两个阶段,本文是第一阶段。 图1 在 AE 开发中,符号选择器有两种实现方式。 一是在程序中直接调用 ArcMap 中的符号选择器,如下所示: 图2 二是自定义符号选择器,如图 1 所示。 由于第一种方式前提是必须安装 ArcGIS Desktop,其界面还是英文的,而对二次开发来说, 大部分用户希望应该是中文界面。 因此开发人员通常选择第二种方式, 本讲也着重讲解第二 种方式。 通过对《ArcGIS Engine+C#实例开发教程》前六讲的学习,我已经假定你已经基本熟悉 C#语 言和 VS2005 的操作,故在下面的教程中,我不准备说明每一步骤的具体操作方法,而只是 说明操作步骤,以节省时间和篇幅。1. 直接调用 ArcMap 中的符号选择器(1)添加 ESRI.ArcGIS.DisplayUI 的引用。 分别在解决方案管理器和代码中添加引用。 (2)添加 TOCControl 的 Double_Click 事件。 (3)实现 TOCControl 的 Double_Click 事件。 因为种方法不是本讲的重点, 故不对代码进行分析, 有兴趣的读者请自行理解或结合后面的 内容理解。代码如下:private void axTOCControl1_OnDoubleClick(object ITOCControlEvents_OnDoubleClickEvent e) { esriTOCControlItem toccItem = esriTOCControlItem.esriTOCControlItemN ILayer iLayer = IBasicMap iBasicMap = object unk = object data = if (e.button == 1) { axTOCControl1.HitTest(e.x, e.y, ref toccItem, ref iBasicMap, ref iLayer, ref unk, ref data); System.Drawing.Point pos = new System.Drawing.Point(e.x, e.y); if (toccItem == esriTOCControlItem.esriTOCControlItemLegendClass) { ESRI.ArcGIS.Carto.ILegendClass pLC = new LegendClassClass(); ESRI.ArcGIS.Carto.ILegendGroup pLG = new LegendGroupClass(); if (unk is ILegendGroup) {sender, pLG = (ILegendGroup) } pLC = pLG.get_Class((int)data); ISymbol pS pSym = pLC.S ESRI.ArcGIS.DisplayUI.ISymbolSelector pSS = new ESRI.ArcGIS.DisplayUI.SymbolSelectorClass(); bool bOK = pSS.AddSymbol(pSym); bOK = pSS.SelectSymbol(0); if (bOK) { pLC.Symbol = pSS.GetSymbolAt(0); } this.axMapControl1.ActiveView.Refresh(); this.axTOCControl1.Refresh(); } } }(4)编译运行即可。 2. 自定义符号选择器AE9.2 提供了 SymbologyControl 控件,极大的方便了图层符号选择器的制作。本讲实现的符 号选择器有如下功能。 用户双击 TOCControl 控件中图层的符号时,弹出选择符号对话框,对话框能够根据图层类 型自动加载相应的符号,如点、线、面。用户可以调整符号的颜色、线宽、角度等参数。还 可以打开自定义的符号文件(*.ServerStyle) ,加载更多的符号。2.1 新建符号选择器窗体新建 Winodws 窗体,命名为 SymbolSelectorFrm,修改窗体的 Text 属性为“选择符号” 。并 添加 SymboloryControl、 PictureBox、 Button、 Label、 NumericUpDown、 GroupBox、 ColorDialog、 OpenFileDialog、ContextMenuStrip 控件。控件布局如下所示: AE9.2 提供了 SymbologyControl 控件,极大的方便了图层符号选择器的制作。本讲实现的符 号选择器有如下功能。 用户双击 TOCControl 控件中图层的符号时,弹出选择符号对话框,对话框能够根据图层类 型自动加载相应的符号,如点、线、面。用户可以调整符号的颜色、线宽、角度等参数。还 可以打开自定义的符号文件(*.ServerStyle) ,加载更多的符号。 图32.2 设置控件属性设置相应控件的相关属性,如下表所示(空则不用修改):控件 SymbologyControl PictureBox LabelName 属性 axSymbologyControl ptbPreview lblColorText 属性其它颜色 Label Label Label Label NumericUpDown NumericUpDown NumericUpDown Button Button Button Button Button GroupBox GroupBox ColorDialog OpenFileDialoglblSize lblWidth lblAngle lblOutlineColor nudSize nudWidth nudAngle btnColor btnOutlineColor btnMoreSymbols btnOK btnCancel groupBox1 groupBox2 colorDialog openFileDialog大小 线宽 角度 外框颜色(设置为空) (设置为空) 更多符号 确定 取消 预览 设置 Filter 属性设置为: Styles 文 件 |*.ServerStyle DialogResult 属性设 为 OKContextMenuStripcontextMenuStripMoreSymbol2.3 添加引用在 解 决 方 案 资 源 管 理 器 中 添 加 ArcGIS Engine 的 ESRI.ArcGIS.Geodatabase 引 用 , 在 SymbolSelectorFrm.cs 文件中添加如下引用代码:using ESRI.ArcGIS.C using ESRI.ArcGIS.D using ESRI.ArcGIS.esriS using ESRI.ArcGIS.SystemUI; using ESRI.ArcGIS.C using ESRI.ArcGIS.G 2.4初始化(1)添加 SymbolSelectorFrm 的全局变量,代码如下: private IStyleGalleryItem pStyleGalleryI private ILegendClass pLegendC private ILayer pL public ISymbol pS public Image pSymbolI (2)修改 SymbolSelectorFrm 的构造函数,传入图层和图例接口。代码如下: /// &summary& /// 构造函数,初始化全局变量 /// &/summary& /// &param name=&tempLegendClass&&TOC 图例&/param& /// &param name=&tempLayer&&图层&/param& public SymbolSelectorFrm(ILegendClass tempLegendClass, ILayer tempLayer) { InitializeComponent(); this.pLegendClass = tempLegendC this.pLayer = tempL } (3)添加 SymbolControl 的 SymbologyStyleClass 设置函数 SetFeatureClassStyle(),代码如下:/// &summary& /// 初 始 化 SymbologyControl 的 StyleClass, 图 层 如 果 已 有 符 号 , 则 把 符 号 添 加 到 SymbologyControl 中的第一个符号,并选中 /// &/summary& /// &param name=&symbologyStyleClass&&&/param& private void SetFeatureClassStyle(esriSymbologyStyleClass symbologyStyleClass) { this.axSymbologyControl.StyleClass = symbologyStyleC ISymbologyStyleClass pSymbologyStyleClass this.axSymbologyControl.GetStyleClass(symbologyStyleClass); if (this.pLegendClass != null) { IStyleGalleryItem currentStyleGalleryItem = new ServerStyleGalleryItem(); currentStyleGalleryItem.Name = &当前符号&; currentStyleGalleryItem.Item = pLegendClass.S pSymbologyStyleClass.AddItem(currentStyleGalleryItem,0); this.pStyleGalleryItem = currentStyleGalleryI } pSymbologyStyleClass.SelectItem(0); } =(4)添加注册表读取函数 ReadRegistry(),此函数从注册表中读取 ArcGIS 的安装路径,代码 如下:/// &summary& /// 从注册表中取得指定软件的路径 /// &/summary& /// &param name=&sKey&&&/param& /// &returns&&/returns& private string ReadRegistry(string sKey) { //Open the subkey for reading Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(sKey, true); if (rk == null) return &&; // Get the data from a specified item in the key. return (string)rk.GetValue(&InstallDir&); }(5)添加 SymbolSelectorFrm 的 Load 事件。根据图层类型为 SymbologyControl 导入相应的 符号样式文件,如点、线、面,并设置控件的可视性。代码如下:private void SymbolSelectorFrm_Load(object sender, EventArgs e) { //取得 ArcGIS 安装路径 string sInstall = ReadRegistry(&SOFTWARE\\ESRI\\CoreRuntime&);//载入 ESRI.ServerStyle 文件到 SymbologyControl this.axSymbologyControl.LoadStyleFile(sInstall + &\\Styles\\ESRI.ServerStyle&); //确定图层的类型(点线面),设置好 SymbologyControl 的 StyleClass,设置好各控件的可见性 (visible) IGeoFeatureLayer pGeoFeatureLayer = (IGeoFeatureLayer)pL switch (((IFeatureLayer)pLayer).FeatureClass.ShapeType) { case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint: this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassMarkerSymbols); this.lblAngle.Visible = this.nudAngle.Visible = this.lblSize.Visible = this.nudSize.Visible = this.lblWidth.Visible = this.nudWidth.Visible = this.lblOutlineColor.Visible = this.btnOutlineColor.Visible = case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline: this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassLineSymbols); this.lblAngle.Visible = this.nudAngle.Visible = this.lblSize.Visible = this.nudSize.Visible = this.lblWidth.Visible = this.nudWidth.Visible = this.lblOutlineColor.Visible = this.btnOutlineColor.Visible = case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon: this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassFillSymbols); this.lblAngle.Visible = this.nudAngle.Visible = this.lblSize.Visible = this.nudSize.Visible = this.lblWidth.Visible = this.nudWidth.Visible = this.lblOutlineColor.Visible = this.btnOutlineColor.Visible = case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryMultiPatch: this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassFillSymbols); this.lblAngle.Visible = this.nudAngle.Visible = this.lblSize.Visible = this.nudSize.Visible = this.lblWidth.Visible = this.nudWidth.Visible = this.lblOutlineColor.Visible = this.btnOutlineColor.Visible = default: this.Close(); } } (6)双击确定按钮和取消按钮,

我要回帖

更多关于 修改状态栏字体颜色 的文章

 

随机推荐