alex_bn_lee

导航

【031】◀▶ 一些心得体会总结

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

●·● 目录:

A0 ………… 64位windows 7 + Visual Studio 2010 + ArcGIS Engine 10.0 操作问题 & 解决
A1 ………… Dock 在布局控件时的使用技巧
       Anchor 在布局控件时的使用技巧
A2 ………… ToolbarControl 的属性设置
A3 ………… TOCControl 的属性设置
A4 ………… MapControl 的属性设置
A5 ………… PageLayoutControl 的属性设置
A6 ………… VS2008打开VS2010项目
A7 ………… Visual Studio 2008“分析 EntityName 时出错。 行 2,位置 81。”报错解决!
A8 ………… 类、接口等的引用传递的理解
A9 ………… DrawShape 与 AddElement 显示图形的区别

G1 ………… Type.Missing 的含义
G2 ………… C# /// 注释 & C# 书签设置

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

            ╔════════╗
╠════╣    第A0个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● 64位windows 7 + Visual Studio 2010 + ArcGIS Engine 10.0 操作问题 & 解决:

参考:http://www.cnblogs.com/Joetao/articles/3415356.html

许多版友在刚刚使用ArcGIS 10做开发的时候,都会遇到这样那样的问题。在担任实习版主的这一个多月里,看到了这么几个与开发环境相关的问题,重复被提到相当多,于是我就做了这个FAQ。
Q:哪儿有10的ArcGIS Engine SDK? A:ArcGIS 10不需要安装单独的Engine开发包,在Desktop的镜像中,安装ArcObjects SDK就可以使用Engine的那些控件做开发了。只在部署的时候还需要Engine Runtime。
Q:为什么在9.3中执行正常的代码,在10中会执行出错,抛出异常COMException A:是如下图这个异常么?
10新增了一个dll,ESRI.ArcGIS.Version,添加这个引用。然后在Main方法中,在窗体启动之前,添加这么一行代码:

  1. RuntimeManager.Bind(ProductCode.EngineOrDesktop);
复制代码

重新编译执行即可。
Q:为什么以前正常的代码,现在都编译都通不过了,提示什么“无法嵌入互操作类型...”
A:你用的是Visual Studio 2010和C# 4吧?如果是,那就对了。这个问题和Engine本身无关。 这是C# 4对COMInterop的一个改进,把创建CoClass时的类名的Class后缀去掉即可。不允许用CoClass本身,而必须用相应的接口来创建对象。 比如,

  1. IPoint p = new PointClass()
复制代码

改为:

  1. IPoint p = new Point()
复制代码

详细的解释可以看这里的:嵌入的互操作类型(如果尝试使用 CoClass 创建嵌入的 COM 类型的实例,则会导致编译器错误)
Q:为什么以前正常的代码,现在一运行就报错,抛出异常BadImageFormatException
A:你的操作系统是64位的Windows吧?可是ArcGIS现在只有32位的,所以必须用X86平台生成项目。 打开项目属性,在“生成”选项卡中找到目标平台,把Any CPU改为x86,重新生成即可。
Q:我要用ArcGIS Engine 10,一定要用Visual Studio 2010吗?
A: 不一定,不论什么版本的Visual Studio和什么版本ArcGIS Engine SDK,都是可以组合的。 因为ArcGIS Engine的SDK是一些COM组件,而C#、VB、VC++对COM的支持一直是有的。

注:Engine SDK可能会检查系统已安装的VisualStudio版本,比如ArcObjects 10 SDK(内含Engine)只在已有10或者08SP1的系统完成安装。当然,如果有办法绕过去,就没问题了。

可能你装上之后工具箱里面的神马MapControl,SceneControl、LicenseControl都没有出来。 这个没关系,添加工具箱项,找到Engine的dll,添加进来,一切Ok
这个问题还是补充地具体一些吧: 1、在VS工具箱内右键,添加选项卡,取名ArcGIS Windows Form 2、在新选项卡上右键,选择项... 3、点浏览,找到ESRI.ArcGIS.AxControls.dll(缺省安装在"C:\Program Files\ArcGIS\DotNet\ESRI.ArcGIS.AxControls.dll"),打开。
4、勾选中新出现的那几个ArcGIS的控件,点确定。

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

            ╔════════╗
╠════╣    第A1个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● Dock 在布局控件时的使用技巧

在布局控件的时候使用 Dock 是很省事的,可以令控件很完美,在使用 Dock 的时候要注意下面几点:

  • Dock 包括 Top、Left、Fill、Right、Bottom,按要求选择!
  • 有的时候Dock不会按照自己的想法去实现,主要原因是控件的层次关系,Dock会优先考虑放在更低下的控件,如下所示,为了让 MapControl 控件可以以 Fill 形式呈现,必须将其放在最顶层,若是放在最底层,则会铺满整个界面,像是 MenuStrip 和 StatusStrip 则要放在最底层,否则就不能完全占据 Top 和 Bottom 了,反正就是优先考虑地层的,然后再考虑顶层的!

●·● Anchor 在布局控件时的使用技巧

直接看下面的例子,Anchor中的Left、Right、Top、Bottom是指与这些边的距离保持不变!

最大化!

设置:

左边的 webBrowser Anchor 设置:Top, Bottom, Left, Right

右上角控件的 Anchor 设置:Top, Right

右下角的 dataGridView Anchor 设置:Top, Bottom, Right

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

            ╔════════╗
╠════╣    第A2个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● ToolbarControl 的属性设置

1. General:

  • Border:边框,0 —— 没有边框、1 —— 有边框。
  • Appearance:外观,0 —— 普通、1 —— 3D效果。
  • Mouse:鼠标样式。
  • Orientation:水平显示 or 垂直显示。
  • Buddy:伙伴控件。
  • Enable:是否可用。
  • Preview in Design Mode:是否在设计视图预览控件。
  • Menu Tracking:选中时,鼠标点击一个 Menu 后,移动鼠标,其他的 Menu 自动被展开!

2. Items:

  • Item:0 —— 普通、1 —— 3D效果。
  • Text:文本显示样式。
  • Update:更新时间。
  • Icon:图标大小。
  • ToolTips:是否显示标记。
  • Themed Drawing:是否有后面的圆角矩形。
  • Show Hidden Item:是否显示隐藏项。
  • Add:增加项。
  • Remove All:删除所有项。

  Add 分项:

  1. Commands:一些基本的命令和工具!

  2. ToolSets:分类!

  3. Menus:以菜单形式存在!

  4. Palettes:以板的形式存在!

    menu 和 palette 如下所示!

3. Color:

  • Transparent:工具栏是透明的。
  • Background Color:设置背景颜色。
  • Fade Color:与上面的 Background Color 建立渐变色。
  • Fill Direction:渐变的方向:水平 or 垂直!

4. 效果预览:

添加 Menu 代码:

//Add existing menus to ToolbarControl.
axToolbarControl1.AddMenuItem("esriControls.ControlsMapViewMenu", -1, false, 0);
axToolbarControl1.AddMenuItem("esriControls.ControlsFeatureSelectionMenu", -1,
    false, 0);
//Create a new file menu.
IToolbarMenu toolbarMenu = new ToolbarMenuClass();
toolbarMenu.Caption = "Map Document";
toolbarMenu.AddItem("esriControls.ControlsOpenDocCommand", -1, 0, false,
    esriCommandStyles.esriCommandStyleIconAndText);
toolbarMenu.AddItem("esriControls.ControlsSaveAsDocCommand", -1, 1, false,
    esriCommandStyles.esriCommandStyleIconAndText);
axToolbarControl1.AddMenuItem(toolbarMenu, -1, false, 0);

axToolbarControl1.MenuTracking = true;

※ 参考:Using the ToolbarControl

※ 参考:http://blog.163.com/hnhanpeng@126/blog/static/264189020069108522553/

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

            ╔════════╗
╠════╣    第A3个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● TOCControl 的属性设置

1. TOCControl 控件:  

  • 相同的如上面所述。
  • Label:
  • Layer:选择 1 后,复选框没办法选!
  • Enable Layer Drag and Drop:是否允许用鼠标拖拽图层。
  • Arrow Key Intercept:是否拦截按键,若选中,则按键仅影响 TOCControl,若不选中,方向键会不自觉地影响 MapControl。

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

            ╔════════╗
╠════╣    第A4个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● MapControl 的属性设置

1. MapControl 控件:  

  • Available Maps:可以选择显示的 Data Frame。

  • Scale:初始比例尺。
  • Rotation:初始旋转角度。

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

            ╔════════╗
╠════╣    第A5个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● PageLayoutControl 的属性设置

1. PageLayoutControl 控件:  

  •  显示设置。

  • 页面设置。

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

            ╔════════╗
╠════╣    第A6个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● VS2008打开VS2010项目

第一步,修改解决方案后缀为sln的文件
  Microsoft Visual Studio Solution File, Format Version 11.00
  # Visual Studio 2010
修改为:
  Microsoft Visual Studio Solution File, Format Version 10.00
  # Visual Studio 2008

第二步,修改项目后缀为csproj的文件,找到第一个4.0改成3.5就好!
  <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
修改为:
  <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

删除:有的时候不存在
  <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>

参考:http://qqhack8.blog.163.com/blog/static/11414798520115892540805/

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

            ╔════════╗
╠════╣    第A7个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● Visual Studio 2008“分析 EntityName 时出错。 行 2,位置 81。”报错解决!

 

1. 报错内容“若要在加载设计器前避免可能发生的数据丢失,必须纠正以下错误: ” 
“分析 EntityName 时出错。 行 2,位置 81。”

2. 如图:

3. 原因如下:

4. 就是中间那个“&”搞的鬼,哎,我怎么就起了个这么悲催的名字呢,以前就经常出现这个问题,有的时候会报错,但有的时候不会报错,靠,原来是这个原因,果断把程序拷到外面,结果就成功了,好吧,看来起名字还是一门学问呢!

参考:http://hi.baidu.com/janic716/blog/item/59165a18073fb3ac4aedbc0a.html 

另外就是,不要让路径的名称太冗长,或是夹杂太多的中文,因为我在用一本书的代码的时候都会出现这个问题,好像就是因为有太多的中文,再加之路径太长了,因为每个文件夹的名字都很长,字符又很乱,所以文件夹和文件的名字要起的简介且规范一点为好!

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

            ╔════════╗
╠════╣    第A8个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● 类、接口等的引用传递的理解

  昨天晚上睡觉的时候突然就想到了这一点,我当时在想,为什么我在另外一个窗体中操作 map(此 map 是调用地图中的 map 的)的时候,会在主窗体中发生变化,之前一直困扰我的就是怎么通过独立的窗体控制主窗体,我突然恍然大悟,当时学习的引用传递就是这个意思了。他们都是共用一个对象的,所以任何对于此对象的操作都会受影响,因为它们本身就是绑定在一起的,这就是为什么我操作独立窗体中的 map 对象的时候,会在主窗体中发生变化。

  另外这也是接口查询(QI)的基石,为什么将接口转来转去的来搞,原因就是它们操作的都是一个对象,只是接口不同,具有的方法和属性不同罢了,从而实现不同的功能!

实例:在按钮的单击事件中新建一个 MapControl 实例,然后操作这个实例的时候,主窗体中的地图也会随之变化!

private void button2_Click(object sender, EventArgs e)
{
    IMapControl4 pmc = axMapControl1.Object as IMapControl4;
    pmc.Rotation = 180;
    pmc.ActiveView.Refresh();
}

实例:将 MapControl 通过类的构造函数传递到独立窗体中,然后操作独立窗体中新建的 MapControl 也会对主窗体中的地图产生影响!

建立独立窗体:

public partial class LayerProperties : Form
{
    IMapControl4 pMapControl;
    IMap pMap;
    IFeatureLayer pLayer;
    IActiveView pActiveView;

    public LayerProperties(IMapControl4 mapControl, IMap map,ILayer layer)  //将主要的内容传递过去,其实传个 MapControl 就足够了
    {
        InitializeComponent();
        pMapControl = mapControl;
        pMap = map;
        pLayer = layer as IFeatureLayer;
        pActiveView = pMap as IActiveView;
    }

    private void 缩放到该要素ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if (pMapControl.Rotation == 0)  //直接操作这个 pMapControl 就会直接影响主窗体的地图了!
        {
            pMapControl.Rotation = 180;
        }
        else
        {
            pMapControl.Rotation = 0;
        }
        pMapControl.ActiveView.Refresh();
    }
}

在主窗体中调用独立窗体:

private void button1_Click(object sender, EventArgs e)
{
    IMap pMap = axMapControl1.Map;
    ILayer pLayer = pMap.get_Layer(0);
    LayerProperties frm = new LayerProperties(axMapControl1.Object as IMapControl4,pMap, pLayer);
    frm.Show();
}

实例: 如下所示:

 1 IPoint pPt = axMapControl2.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(e.x,e.y);
 2 IMarkerElement pMarkerElement = new MarkerElementClass();
 3 ISimpleMarkerSymbol pMarkerSymbol = new SimpleMarkerSymbolClass();
 4 pMarkerSymbol.Color = GetColor(255, 0, 0);
 5 pMarkerSymbol.Size = 10;
 6 pMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCross;
 7 IElement pElement = pMarkerElement as IElement;
 8 pElement.Geometry = pPt;
 9 pMarkerElement.Symbol = pMarkerSymbol;  //这里虽然用的是 pMarkerElement,但是效果就会直接影响 pElement!
10 IGraphicsContainer pGraphicsContainer = axMapControl2.Map as IGraphicsContainer;
11 pGraphicsContainer.AddElement(pElement, 0);
12 axMapControl2.ActiveView.Refresh();

对于第 11 句来说,下面的写法也可以!实现的效果是一样的,因为本身他们就是一个东西,不同的名字罢了!

pGraphicsContainer.AddElement(pMarkerElement as IElement, 0);

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

            ╔════════╗
╠════╣    第A9个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● DrawShape 与 AddElement 显示图形的区别

  前者在操作的时候更加方便,但是这个图形是临时的,一旦刷新地图,这些东西就没了,因此也没有办法存储,相比之下,AddElement 是实体的操作,放大地图,图形也跟着变大,而且可以存储在地图中!对比下面:

IMapControl4 m_mapControl = m_hookHelper.Hook as IMapControl4;
IEnvelope pRectangle = m_mapControl.TrackRectangle();

ISimpleLineSymbol pSimpleLineSym = new SimpleLineSymbol();
pSimpleLineSym.Color = GetColor(0, 0, 0);
pSimpleLineSym.Width = 2;

ISimpleFillSymbol pSimpleFillSym = new SimpleFillSymbol();
pSimpleFillSym.Color = GetColor(0, 255, 0);
pSimpleFillSym.Outline = pSimpleLineSym;

object symbol = pSimpleFillSym;
m_mapControl.DrawShape(pRectangle, ref symbol);
IMapControl4 m_mapControl = m_hookHelper.Hook as IMapControl4;
IScreenDisplay pScreenDisplay = m_mapControl.ActiveView.ScreenDisplay;
IGraphicsContainer pGraphicsContainer = m_mapControl.Map as IGraphicsContainer;
IRubberBand pRubberPolygon = new RubberPolygon();
IPolygon pPolygon = pRubberPolygon.TrackNew(pScreenDisplay, null) as IPolygon;

ISimpleLineSymbol pSimpleLineSym = new SimpleLineSymbol();
pSimpleLineSym.Color = GetColor(0, 0, 0);
pSimpleLineSym.Width = 2;

ISimpleFillSymbol pSimpleFillSym = new SimpleFillSymbol();
pSimpleFillSym.Color = GetColor(0, 255, 0);
pSimpleFillSym.Outline = pSimpleLineSym;

IElement pEle = new PolygonElement();
pEle.Geometry = pPolygon;
IFillShapeElement pFillShapeEle = pEle as IFillShapeElement;
pFillShapeEle.Symbol = pSimpleFillSym;

pGraphicsContainer.AddElement(pEle, 0);
m_mapControl.ActiveView.Refresh();

  对于后者来说是增加元素,因此最后要刷新一下,否则没办法显示,前者则只是画在临时的地图表面!

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

            ╔════════╗
╠════╣    第G1个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● Type.Missing 的含义

  表示 Type 信息中的缺少值。 使用 Missing 字段通过反射进行调用,以获取参数的默认值。如果传入一个参数值的 Missing 字段,并且该参数没有默认值,则引发 ArgumentException。 一般在ComInterop使用比较多。如果接触过VSTO,就会发现有很多地方要用到Type.Missing字段。许多C++写的com组件API参数列表中有很多默认值,而C#是没有参数默认值的。使用这个字段可以直接使用API参数的默认值。

※ 官方帮助参考:http://msdn.microsoft.com/zh-cn/library/system.type.missing.aspx?TPSecNotice

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

            ╔════════╗
╠════╣    第G2个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● C# /// 注释 & C# 书签设置

  /// 的注释有特殊的作用,不仅仅是注释,通过下面的实例来体会!

/// <summary>
/// shp文件的完整路劲
/// </summary>
string shapeFileFullName = string.Empty;

  其中中间的部分是对于变量的描述,在后面的程序中用到此变量的时候,可以显示这个描述!(错字都显示出来了!哈!)

  对于函数来说,一方面可以给函数本身做注释,还可以给参数做注释!

/// <summary>
/// 获取点数据
/// </summary>
/// <param name="surveyDataFullName">测量数据全路径名称</param>
/// <returns></returns>
private List<CPoint> GetAllPoint(string surveyDataFullName)
{
    ...
}

※ 官方帮助参考:http://msdn.microsoft.com/zh-cn/library/5ast78ax.aspx

※ 书签设置参考:http://topic.csdn.net/u/20120112/12/38f1b889-0795-4f99-b0f1-1b9b2c827ba1.html

 

 

 

 

 

posted on 2012-04-13 09:17  McDelfino  阅读(1601)  评论(0编辑  收藏  举报