当前位置:软件学习 > 其它软件 >>

连载-基于插件技术的GIS应用框架(C# + ArcEngine9.3)(五)

[align=center]基于插件技术的GIS应用框架(C# + ArcEngine9.3)(五)

                                --------------------------插件初始化(1)[/align]

在第四节中,我们论及了插件的XML保存格式,对于各个XML节点的属性也有了一个大概的了解,下面,我们就如何利用DevExpress套件就这些插件的加载进行详细的剖析。首先,我们必须从已经编译好的DLL中获取插件的类型信息,这就需要利用C#所提供的反射机制。

一、插件的反射

/// 根据反射机制产生插件对象并将其放入插件池
    public class PluginActivator
    {
        /// 定义插件文件所在路径

   private static readonly string pluginpath = System.Windows.Forms.Application.StartupPath;

   /// 获取插件并加入到插件池
        public static PluginCollection ActivatePluginsFromDll()
        {
            //存储插件的容器
            PluginCollection _PluginCol = new PluginCollection();
            //获得插件文件夹中的每一个dll文件
            string[] _files = Directory.GetFiles(pluginpath, "*.dll");
            foreach (string _pluginfile in _files)
            {
                Assembly _assembly = Assembly.LoadFrom(_pluginfile );
                if (_assembly != null)
                {
                    Type[] _types = null;
                    try
                    {
                        _types = _assembly.GetTypes();
                    }
                    catch (ReflectionTypeLoadException ex)
                    {
                    }
                    finally
                    {
                        foreach (Type _type in _types)
                        {
                            //获得一个插件对象的接口信息
                            Type[] _Inte易做图ceList = _type.GetInte易做图ces();
                            //遍历接口
                            foreach (Type Inte易做图ceType in _Inte易做图ceList)
                            {
                                //将插件添加到相应的插件池中
                                switch (Inte易做图ceType.FullName)
                                {
                                    case "AxeMap.PluginEngine.Inte易做图ce.IAxCommand":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Inte易做图ce.IAxTool":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Inte易做图ce.IAxEdit":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Inte易做图ce.IAxCombobox":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Inte易做图ce.IAxColorPicker":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Inte易做图ce.IAxSubItem":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Inte易做图ce.IAxContentsView":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Inte易做图ce.IAxDockableWindowDef":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }
                    }

                }
            }
            return _PluginCol;
        }

关于如何反射对象,C#提供了很多的例子,具体就不再叙述,下面我们将结合DevExpress套件重点介绍各类插件的加载过程。

二、插件的初始化

1.Command插件

private DevExpress.XtraBars.BarButtonItem CreateUICommand(IAxCommand cmd, string itemnamespace, string customcaption)
{
      if (cmd == null)
      {
          return null;
      }            
      (cmd as ICommand).OnCreate(_App);   //调用esriSystemUI.ICommand插件的OnCreate,将框架对象传递给插件对象

 BarButtonItem UICmd = new BarButtonItem();  //产生一个UI层的按钮对象,并根据插件的属性进行相应设置  
      UICmd .Hint = (cmd as ICommand).Tooltip;
      if (customcaption != "")
      {
           UICmd .Caption = customcaption; //优先显示插件配置文件中插件的标题
      }
      else
      {
           UICmd .Caption = (cmd as ICommand).Caption;
      }

 //加载命令插件的bitmap或icon

 System.IntPtr _Handle = (System.IntPtr)(cmd as ICommand).Bitmap;
      if (_Handle.ToInt32() != 0)
      {
          try
          {
               UICmd .Glyph = System.Drawing.Bitmap.FromHicon(_Handle); 
          }
          catch
          {
               UICmd.Glyph = System.Drawing.Image.FromHbitmap(_Handle); 
          }
       }

  UICmd.Enabled = (cmd as ICommand).Enabled;
       if ((cmd as ICommand).Checked)
       {
            UICmd .ButtonStyle = BarButtonStyle.Check;
       }

  //记录命令插件的类型到 Tag 属性
       UICmd.Tag = cmd.ToString();

  //记录命令插件的Category属性,由于使用DevExpress,设置UICmd的分类很麻烦,这是DevExpress的不好用的地方

  IEnumerator categoryEnum = _barManager.Categories.GetEnumerator();
       string cmdCategory;
       categoryEnum.Reset();
       while (categoryEnum.MoveNext() == true)
       {
           cmdCategory = ((BarManagerCategory)categoryEnum.Current).ToString();
           if (cmdCategory == (cmd as ICommand).Category)
           {
               UICmd.Category = (BarManagerCategory)categoryEnum.Current;
               break;
            }
       }
       //委托事件

  UICmd.ItemClick += new ItemClickEventHandler(UICmd_Click);
       //将生成的UICmd添加到CommandManager中,DevExpress提供一个统一管理器,管理所有的工具条对象
       _barManager.Items.AddRange(new DevExpress.XtraBars.BarItem[] { UICmd});

  _UIControlList.Add(itemnamespace, UICmd);
       return UICmd;
}

2.ICombobox插件(以编辑任务列表为例)

编辑任务列表的插件实现:

namespace AxeMap.MapEdit
{
    public class EditTasks : IAxCombobox
    {
        private AxeMapEngine.Inte易做图ce.IAxApplication _App;
        private string _EditTask;
        private List<string> _EditTaskList = null;

   public EditTasks()
        {
            _EditTaskList = new List<string>();
            _EditTaskList.Add("新建要素");
            _EditTaskList.Add("分割要素");
            _EditTaskList.Add("自动闭合多边形");
        }

        #region IAxCombobox 成员

   public string Name
        {
            get { return "EditTasks"; }
        }

    public string Caption
        {
            get { return "编辑任务"; }
        }

    public bool ShowCaption
        {
            get { return true; }
        }

    public System.Collections.ICollection Items
        {
            get { return _EditTaskList; }
        }

   public string Text
        {
            get
            {
                if (_App.MapEngine.IsBeingEdited)
                {
                    return _EditTask;
                }
                else
                {
                    return "";
                }
            }
        }

   public string Category
        {
            get { return "编辑"; }
        }

   public bool Enabled
        {
            get
            {
                return ((_App.MapEngine.IsBeingEdited) && (_App.MapEngine.CurrentFeatureLayer != null));

        }
        }        
        public bool Editable  //用户只能从列表中选择,不能修改列表
        {
            get { return false; }
        }        
        public int Width     //列表显示多宽
        {
            get { return 186; }
        }      
        public int DropDownRows
        {
            get { return 9; }
        }

   public string Tooltip
        {
            get { return "编辑任务"; }
        }

   public string Message
        {
            get { return "编辑任务"; }
        }

    public void OnKeyPress()
        {
 
        }

    public void OnKeyDown()

    {

    }

    public void EditValueChanged(string newText)
        {
            _EditTask = newText;
            if (_EditTask == "")
            {
                _App.MapEngine.CurrentEditTask = null;
            }
            else 
            {
                _App.MapEngine.CurrentEditTask = null;
                switch (_EditTask)
                {
                    case "":                  _App.MapEngine.SetEditTask(""); break;
                    case "新建要素":          _App.MapEngine.SetEditTask("Create New Feature"); break;
                    case "分割要素":          _App.MapEngine.SetEditTask("Cut Features"); break;
                    case "自动闭合多边形":    _App.MapEngine.SetEditTask("Auto Complete Polygon"); break;
                    default:                  _App.MapEngine.SetEditTask("Create New Feature"); break;
                }
            }
        }

   private void WorkspaceEvents_OnStartEditing()
        {
             _EditTask = _EditTaskList.ToArray().GetValue(0).ToString();
             EditValueChanged(_EditTask);
        }

    private void WorkspaceEvents_OnStopEditing(bool bSave)
        {
            _EditTask = "";
            EditValueChanged(_EditTask);
        }

   public void OnCreate(AxeMapEngine.Inte易做图ce.IAxApplication hook)
        {
            if (hook != null)
            {
                this._App = hook;   //获取框架程序对象
                _App.MapEngine.WorkspaceEvents.OnStartEditing += new AxWorkspaceStartEditingEventsHandler(WorkspaceEvents_OnStartEditing);   //通过事件代理响应框架中当前编辑工作空间的事件
                _App.MapEngine.WorkspaceEvents.OnStopEditing += new AxWorkspaceStopEditingEventsHandler(WorkspaceEvents_OnStopEditing);
            }
        }

  #endregion
    }
}

 


 
--------------------编程问答-------------------- ArcEngine对象间的关系是相当的不明确.. --------------------编程问答-------------------- 连载还未结束 ,看完最后结果,您再做评价。框架不是用来说明ArcEngine对象间的关系的,这点你要搞清楚。 --------------------编程问答-------------------- 没分发帖了,有兴趣的哥们去我博客看吧, 我在那发,如若未能访问CSDN的博客,那就去 http://blog.sina.com.cn/burningnight --------------------编程问答-------------------- 楼主辛苦了 --------------------编程问答-------------------- CSDN博客里 将大致的设计思路和核心部分的一些代码,诸如自己实现捕捉、编辑任务列表、编辑图层列表及草图工具的代码都贴了出来,有兴趣可以研究一下,其实几个接口综合起来研究,并不难。之前试用delphi 来实现的,后来我照搬了原来的实现,区别在与c#在处理IActiveView事件和IWorkspace的事件可以更简单,事实证明用C#确实不错,不过运行起来,感觉比delphi版本的要慢,这是显而易见的了。
补充:企业软件 ,  地理信息系统
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,