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

来源:互联网 发布:fd软件是什么 编辑:程序博客网 时间:2024/06/08 06:00

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

                                --------------------------插件初始化(1)

在第四节中,我们论及了插件的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[] _InterfaceList = _type.GetInterfaces();
                            //遍历接口
                            foreach (Type InterfaceType in _InterfaceList)
                            {
                                //将插件添加到相应的插件池中
                                switch (InterfaceType.FullName)
                                {
                                    case "AxeMap.PluginEngine.Interface.IAxCommand":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Interface.IAxTool":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Interface.IAxEdit":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Interface.IAxCombobox":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Interface.IAxColorPicker":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Interface.IAxSubItem":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Interface.IAxMenuDef":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Interface.IAxToolBarDef":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Interface.IAxContentsView":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    case "AxeMap.PluginEngine.Interface.IAxDockableWindowDef":
                                        GetPlugin(_PluginCol, _type);
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }
                    }

                }
            }
            return _PluginCol;
        }

   /// 提取插件
        private static void GetPlugin(PluginCollection pluginColl, Type _type)
        {
            IAxPlugin plugin = null;
            try
            {
                //创建插件实例
                plugin = System.Activator.CreateInstance(_type) as IAxPlugin;
                //MessageBox.Show(_type.ToString());
            }
            catch (Exception ex)
            {
            }
            finally
            {
                if (plugin != null)
                {
                    if (!pluginColl.Contains(plugin))
                    {
                        pluginColl.Add(plugin);
                    }
                }
            }
        }
    }

关于如何反射对象,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插件(以编辑任务列表为例)

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

using System;
    using System.Collections.Generic;
    using System.Text;
    using AxeMap.AxeMap;
    using AxeMap.PluginEngine.Interface;
    using AxeMap.AxeMapEngine.Interface;
    using AxeMap.AxeMapEngine.Implement;

namespace AxeMap.MapEdit
{
    public class EditTasks : IAxCombobox
    {
        private AxeMapEngine.Interface.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.Interface.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
    }
}