欢迎您来到GIS动力

加入收藏 免费注册 用户登陆 帮助中心
首页 新闻动态 技术专栏 银杏树下 学习考研 软件下载 求职招聘 许愿瓶 节日祝福 用户中心 精彩推荐 资源搜索 地图
专栏导航: AO开发 | SO开发 | ArcGIS桌面 | 超图桌面 | 开发语言 | 数据库 | WebGIS | 银杏文学 | 研究生考题 | FreeMap FreeTalk
   您现在位于: 首页技术专栏ArcGIS应用与开发ArcGIS桌面 → 正文
How to create an attractive (and functional) toolbar for ArcGIS Desktop
08-07-02 16:40:33 作者:mrrichie 出处:http://mrrichie.spaces.live.com

How to create an attractive (and functional) toolbar for ArcGIS Desktop

ESRI's ArcGIS Desktop product includes the applications ArcCatalog, ArcMap, ArcScene and ArcGlobe. The user interfaces for all four applications can be heavily customized, for example, developers can deploy custom toolbars and buttons.

Below is an example of a custom toolbar for ArcMap. The toolbar is developed as a series of COM classes (or .NET classes with interop). The classes must use interfaces defined in the ArcGIS Desktop SDK such as IToolbarDef, IMenuDef, ICommand and IToolControl. For more information on this or other interfaces please visit EDN.

image 
Before (standard implementation)

With ArcGIS Desktop 9.2, development of toolbars was made much easier with the inclusion of base classes in the ArcGIS .NET SDK. However, the basic look and feel of the ArcGIS Desktop user interface has not changed since it was first released in 2000.

In this article, I will describe how to implement a modern UI in an ArcGIS Desktop application using .NET 2.0. This is achieved by hosting a .NET 2.0 ToolStrip inside a traditional ESRI Toolbar.  This is the result:

image
After (using hosted .NET ToolStrip)

With minimal effort it is possible to create an attractive, functional and efficient toolbar. To summarize the benefits of a hosted ToolStrip:

  • Office-style mouse-over shading,
  • Button icons with an optional alpha channel (see PNG). An alpha channel can be used for anti-aliasing with a background colors so that images appear to be smooth with no sharp edges.
  • Button icons can support up to 24bit colors.  ESRI buttons only support 4bit colors, that is, only 16 unique colors. With 16 colors, anti-aliasing is practically impossible.
  • An entire toolbar need only expose two COM classes, one for the toolbar and one for the hosting component (ToolControl). This reduces the .NET to COM overhead and makes deployment a lot easier, especially for larger toolbars.
  • Code consolidation. All UI components can be hosted within a single .NET user control.  Less overhead and more code re-used.
  • Dynamic toolbar. It is easy to change the toolbar's appearance at runtime.  For example, buttons can be added or removed during runtime.

But there is always a catch!  :-)  The only disadvantage that I have found is that toolbars cannot be resized at runtime.

The code below will create the ArcMap toolbar shown above.  To use the code, create a new C# Class Library in Microsoft Visual Studio 2005.  In the project properties, tick Register for COM interop.

Please note that the code and methodology used in this post is not endorsed or supported by ESRI. Use this code at your own risk.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

using Microsoft.Win32;

using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.SystemUI;

namespace ESRI.ArcGIS.DeveloperSamples.ToolbarNet {
    // .NET UserControl that hosts a ToolStrip
    [ComVisible(false)]
    public class UserControlTest : UserControl{
        private enum Action { None, Cut, Copy, Paste, Delete, Zoom25, Zoom50, Zoom100 }
        private IApplication m_application = null;
        public UserControlTest() {
            // Get .NET Bitmaps
            Assembly assembly = Assembly.GetAssembly(typeof(Form));
            Bitmap bitmap1 = new Bitmap(assembly.GetManifestResourceStream("System.Windows.Forms.cut.bmp"));
            Bitmap bitmap2 = new Bitmap(assembly.GetManifestResourceStream("System.Windows.Forms.copy.bmp"));
            Bitmap bitmap3 = new Bitmap(assembly.GetManifestResourceStream("System.Windows.Forms.paste.bmp"));
            Bitmap bitmap4 = new Bitmap(assembly.GetManifestResourceStream("System.Windows.Forms.delete.bmp"));
            bitmap1.MakeTransparent(Color.Fuchsia);
            bitmap2.MakeTransparent(Color.Fuchsia);
            bitmap3.MakeTransparent(Color.Fuchsia);
            bitmap4.MakeTransparent(Color.Fuchsia);

            // Create Dropdown Button
            ToolStripDropDownButton toolStripDropDownButton = new ToolStripDropDownButton();
            toolStripDropDownButton.Text = "Zoom";
            toolStripDropDownButton.DropDownItems.Add(new ToolStripMenuItemAction("25%", Action.Zoom25));
            toolStripDropDownButton.DropDownItems.Add(new ToolStripMenuItemAction("50%", Action.Zoom50));
            toolStripDropDownButton.DropDownItems.Add(new ToolStripMenuItemAction("100%", Action.Zoom100));
            toolStripDropDownButton.DropDownItemClicked += new ToolStripItemClickedEventHandler(
                this.ToolStrip_DropDownItemClicked);

            // Create Toolstrip
            ToolStrip toolstrip = new ToolStrip();
            toolstrip.GripStyle = ToolStripGripStyle.Hidden;
            toolstrip.Items.Add(new ToolStripButtonAction(bitmap1, Action.Cut));
            toolstrip.Items.Add(new ToolStripButtonAction(bitmap2, Action.Copy));
            toolstrip.Items.Add(new ToolStripButtonAction(bitmap3, Action.Paste));
            toolstrip.Items.Add(new ToolStripSeparator());
            toolstrip.Items.Add(new ToolStripButtonAction(bitmap4, Action.Delete));
            toolstrip.Items.Add(new ToolStripSeparator());
            toolstrip.Items.Add(toolStripDropDownButton);
            toolstrip.Stretch = true;
            toolstrip.MouseEnter += new EventHandler(this.Toolstrip_MouseEnter);
            toolstrip.ItemClicked += new ToolStripItemClickedEventHandler(this.Toolstrip_ItemClicked);

            // Add Toolbar. Set Size.
            this.Controls.Add(toolstrip);
            this.Width = 160;
        }
        public IApplication Application {
            set { this.m_application = value; }
        }
        private void Toolstrip_MouseEnter(object sender, EventArgs e) {
            ToolStrip toolStrip = sender as ToolStrip;
            if (toolStrip == null) { return; }
            toolStrip.Focus();
        }
        private void ToolStrip_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e) {
            ToolStripMenuItemAction toolStripMenuItemAction = e.ClickedItem as ToolStripMenuItemAction;
            if (toolStripMenuItemAction == null) { return; }
            this.ExecuteAction(toolStripMenuItemAction.Action);
        }
        private void Toolstrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e) {
            ToolStripButtonAction toolStripButtonAction = e.ClickedItem as ToolStripButtonAction;
            if (toolStripButtonAction == null) { return; }
            this.ExecuteAction(toolStripButtonAction.Action);
        }
        private void ExecuteAction(Action action) {
            switch (action) {
                case Action.Cut:
                case Action.Copy:
                case Action.Paste:
                case Action.Delete:
                case Action.Zoom25:
                case Action.Zoom50:
                case Action.Zoom100:
                    MessageBox.Show(action.ToString());
                    break;
                default:
                    break;
            }
        }
        // Subclassed ToolStripButton
        private class ToolStripButtonAction : ToolStripButton {
            private readonly Action m_action = Action.None;
            public ToolStripButtonAction(Image image, Action action) : base(image) {
                this.m_action = action;
            }
            public Action Action {
                get { return this.m_action; }
            }
        }
        private class ToolStripMenuItemAction : ToolStripMenuItem {
            private readonly Action m_action = Action.None;
            public ToolStripMenuItemAction(string text, Action action) : base(text) {
                this.m_action = action;
            }
            public Action Action {
                get { return this.m_action; }
            }
        }
    }

    // The ESRI ArcMap Command that hosts the User Control
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid(ApplicationGuid.GUID_COMMAND_TEST)]
    public sealed class CommandHost : EsriCommandControlMx {
        public CommandHost() : base() {
            this.m_control = new UserControlTest();
        }
        public override void OnCreate(object hook) {
            base.OnCreate(hook);
            if (hook != null) {
                ((UserControlTest)this.m_control).Application = (IApplication)hook;
            }
        }
    }

    // The ESRI ArcMap Toolbar
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid(ApplicationGuid.GUID_TOOLBAR_TEST)]
    public sealed class ToolbarTest : EsriToolbarMx {
        public ToolbarTest() : base() {
            this.m_caption = "Test";
            this.m_commands.Add(new EsriToolbarCommand(new Guid(ApplicationGuid.GUID_COMMAND_TEST), false));
        }
    }

    // The Abstract ESRI ArcMap Toolbar
    [ComVisible(false)]
    public abstract class EsriToolbarMx : EsriToolbar {
        private const string IMPLEMENT_CATEGORIES = "\\Implemented Categories\\";
        [ComVisible(false)]
        [ComRegisterFunction()]
        private static void RegisterFunction(string regKey) {
            Registry.ClassesRoot.CreateSubKey(regKey.Substring(18) + IMPLEMENT_CATEGORIES + 
                EsriRegistry.COMPONENT_MX_TOOLBAR);
        }
        [ComVisible(false)]
        [ComUnregisterFunction()]
        private static void UnregisterFunction(string regKey) {
            Registry.ClassesRoot.DeleteSubKey(regKey.Substring(18) + IMPLEMENT_CATEGORIES +
                EsriRegistry.COMPONENT_MX_TOOLBAR);
        }
    }

    // Abstract ESRI Toolbar
    [ComVisible(false)]
    public abstract class EsriToolbar : IToolBarDef {
        private const string SUFFIX = "_TOOLBAR";
        protected List<EsriToolbarCommand> m_commands = new List<EsriToolbarCommand>();
        protected string m_caption = null;
        public void GetItemInfo(int pos, IItemDef itemDef) {
            itemDef.ID = this.m_commands[pos].Guid.ToString("B");
            itemDef.Group = this.m_commands[pos].Group;
        }
        public string Caption {
            get { return this.m_caption; }
        }
        public string Name {
            get { return this.m_caption.ToUpper().Replace(" ", "") + SUFFIX; }
        }
        public int ItemCount {
            get { return this.m_commands.Count; }
        }
    }

    // Abstract ESRI Toolbar Item
    [ComVisible(false)]
    public class EsriToolbarCommand {
        private readonly Guid m_guid = Guid.Empty;
        private readonly bool m_group = false;
        public EsriToolbarCommand(Guid guid, bool group) {
            this.m_guid = guid;
            this.m_group = group;
        }
        public Guid Guid {
            get { return this.m_guid; }
        }
        public bool Group {
            get { return this.m_group; }
        }
    }

    // Abstract ESRI ArcMap Command Tool Control
    [ComVisible(false)]
    public abstract class EsriCommandControlMx : EsriCommandControl {
        private const string IMPLEMENT_CATEGORIES = "\\Implemented Categories\\";
        [ComVisible(false)]
        [ComRegisterFunction()]
        private static void RegisterFunction(string regKey) {
            Registry.ClassesRoot.CreateSubKey(regKey.Substring(18) + IMPLEMENT_CATEGORIES +
                EsriRegistry.COMPONENT_MX_COMMAND);
        }
        [ComVisible(false)]
        [ComUnregisterFunction()]
        private static void UnregisterFunction(string regKey) {
            Registry.ClassesRoot.DeleteSubKey(regKey.Substring(18) + IMPLEMENT_CATEGORIES +
                EsriRegistry.COMPONENT_MX_COMMAND);
        }
    }

    // Abstract ESRI Command Tool Control
    [ComVisible(false)]
    public abstract class EsriCommandControl : EsriCommand, IToolControl {
        protected ICompletionNotify m_completionNotify = null;
        protected UserControl m_control = null;
        public virtual bool OnDrop(esriCmdBarType barType) {
            return true;
        }
        public virtual void OnFocus(ICompletionNotify complete) {
            this.m_completionNotify = complete;
            // Can add UI update here
        }
        public int hWnd {
            get { return this.m_control.Handle.ToInt32(); }
        }
    }

    // Abstract ESRI Command
    [ComVisible(false)]
    public abstract class EsriCommand : ICommand {
        protected string m_category = null;
        protected string m_message = null;
        protected string m_caption = null;
        protected string m_tooltip = null;
        protected IApplication m_application = null;
        protected Bitmap m_bitmap = null;
        private IntPtr m_hBitmap = IntPtr.Zero;

        [DllImport("gdi32.dll")]
        protected static extern bool DeleteObject([In] IntPtr hObject);

        protected EsriCommand() { }
        ~EsriCommand() {
            if (this.m_hBitmap != IntPtr.Zero) {
                DeleteObject(this.m_hBitmap);
            }
            this.m_bitmap = null;
            this.m_application = null;
        }
        public virtual void OnClick() { }
        public string Message {
            get { return this.m_message; }
        }
        public int Bitmap {
            get {
                if (this.m_hBitmap == IntPtr.Zero) {
                    if (this.m_bitmap != null) {
                        this.m_hBitmap = this.m_bitmap.GetHbitmap();
                    }
                }
                return this.m_hBitmap.ToInt32();
            }
        }
        public virtual void OnCreate(object hook) {
            if (hook != null) {
                this.m_application = (IApplication)hook;
            }
        }
        public string Caption {
            get { return this.m_caption; }
        }
        public string Tooltip {
            get { return this.m_tooltip; }
        }
        public int HelpContextID {
            get { return 0; }
        }
        public string Name {
            get { return this.m_category.Replace(" ", "") + "_" + this.m_caption.Replace(" ", ""); }
        }
        public virtual bool Checked {
            get { return false; }
        }
        public virtual bool Enabled {
            get { return true; }
        }
        public string HelpFile {
            get { return null; }
        }
        public string Category {
            get { return this.m_category; }
        }
    }

    // List of ESRI Guids
    [ComVisible(false)]
    public static class EsriRegistry {
        public const string COMPONENT_MX_COMMAND = "{B56A7C42-83D4-11D2-A2E9-080009B6F22B}";
        public const string COMPONENT_MX_TOOLBAR = "{B56A7C4A-83D4-11D2-A2E9-080009B6F22B}";
    }

    // List of hardcoded application guids
    [ComVisible(false)]
    public static class ApplicationGuid {
        public const string GUID_COMMAND_TEST = "D4E1C9EB-F2E4-4BD1-AF13-3868E555D322";
        public const string GUID_TOOLBAR_TEST = "2B8966B6-C623-4F83-A376-53042F667B13";
    }
}

(本文已被浏览 次)
发布人:admin
推荐给好友:发送给好友
上篇新闻:
下篇新闻:
相关评论
发表我的评论
  • 尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法;
  • 本站有权保留或删除您发表的任何评论内容;
  •   相关文章  
    如何在Toolbar控件上添加Combobox等其他控件

    关于我们友情链接 ┋ 与我在线 ┋ 管理 ┋ TOP
     
    网站当前版本:GisPower CMS V3.0
    『GIS 动力』- http://www.gispower.org/
    联系我们:webmaster#gispower.org
    Copyright (c) 2003-2007 GisPOwer.Org. All Rights Reserved.
     

                   滇ICP备05006901号