alex_bn_lee

导航

< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

统计

【027】TOCControl上实现右键

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

●·● 目录:

A1 ………… 第一种方法:contextMenuStrip
A2 ………… 第二种方法:IToolbarMenu
1A ………… ICommandSubType 接口
2A ………… IToolbarMenu 接口

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

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

●·● 第一种方法:contextMenuStrip

第一步:新建另外一个窗体

  • 首先要定义一个全局变量 ILayer。
  • 窗体要带参数,以便将 ILayer 传递过来。
  • 获取属性列表。
复制代码
        ILayer pLayer;            //定义一个虚拟的ILayer
public Form2(ILayer layer)
{
InitializeComponent();
pLayer = layer; //将赋值的layer再赋值给pLayer,这样pLayer就是实体了
}

private void Form2_Load(object sender, EventArgs e)
{
IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer;
IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
IFeatureCursor pFeatureCursor = pFeatureClass.Search(null, false);
IFeature pFeature = pFeatureCursor.NextFeature();
IFields pFields = pFeatureClass.Fields;

DataTable pTable = new DataTable();
for (int i = 0; i < pFields.FieldCount; i++) //获取所有列
{
DataColumn pColumn = new DataColumn(pFields.get_Field(i).Name);
pTable.Columns.Add(pColumn);
}
while (pFeature != null)
{
DataRow pRow = pTable.NewRow();
for (int i = 0; i < pFields.FieldCount; i++) //添加每一列的值
{
pRow[i] = pFeature.get_Value(i);
}
pTable.Rows.Add(pRow);
pFeature = pFeatureCursor.NextFeature();
}
dataGridView1.DataSource = pTable;
}
复制代码

第二步:建立右键菜单项

  • 添加一个 ContextMenuStrip 控件,然后增加几个菜单项。
  • 特别注意加入一个菜单项为“显示属性”。
  • 判断在什么情况下显示右键菜单。
复制代码
        ILayer m_Layer;  //沟通图层
private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
{
if (e.button == 2)
{
esriTOCControlItem Item = esriTOCControlItem.esriTOCControlItemNone;
IBasicMap pBasicMap = null;
ILayer pLayer = null;
object other = null;
object index = null;
axTOCControl1.HitTest(e.x, e.y, ref Item, ref pBasicMap, ref pLayer, ref other, ref index); //实现赋值
m_Layer = pLayer;
if (Item == esriTOCControlItem.esriTOCControlItemLayer) //点击的是图层的话,就显示右键菜单
{
contextMenuStrip2.Show(axTOCControl1, new System.Drawing.Point(e.x, e.y));
//显示右键菜单,并定义其相对控件的位置,正好在鼠标出显示
}
}

}

private void 显示属性ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(m_Layer); //定义窗体,注意窗体的参数
frm.Text = "Attributes of " + m_Layer.Name; //显示标题
frm.ShowDialog(); //以对话框形式显示窗体
}
复制代码

效果如下所示:

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

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

●·● 第二种方法:IToolbarMenu

第一步:新建菜单框架:

IToolbarMenu m_TOCMapMenu = new ToolbarMenu();
IToolbarMenu m_TOCLayerMenu = new ToolbarMenu();

第二步:在菜单框架中加入菜单项,用 AddItem 方法实现:

复制代码
m_TOCLayerMenu.Caption = "Sub Menu";       //二级菜单设置名称
m_TOCLayerMenu.AddItem(new ControlsMapZoomInToolClass(), 0, 0, false, esriCommandStyles.esriCommandStyleIconAndText);
m_TOCLayerMenu.AddItem(new ControlsMapZoomInToolClass(), 0, 1, true, esriCommandStyles.esriCommandStyleIconAndText);
m_TOCLayerMenu.AddItem(new ControlsMapZoomInToolClass(), 0, 2, false, esriCommandStyles.esriCommandStyleIconAndText);
m_TOCLayerMenu.SetHook(axMapControl1);         //作用在 MapControl 上面

m_TOCMapMenu.AddItem(new ControlsAddDataCommandClass(), 0, 0, false, esriCommandStyles.esriCommandStyleIconAndText);
m_TOCMapMenu.AddItem(new ControlsMapFullExtentCommand(), 0, 1, false, esriCommandStyles.esriCommandStyleIconAndText);
m_TOCMapMenu.AddItem(new ControlsMapZoomInToolClass(), 0, 2, true, esriCommandStyles.esriCommandStyleIconAndText);
m_TOCMapMenu.AddItem(new ControlsMapZoomOutToolClass(), 0, 3, false, esriCommandStyles.esriCommandStyleIconAndText);
m_TOCMapMenu.AddItem(new ControlsPagePanToolClass(), 0, 4, false, esriCommandStyles.esriCommandStyleIconAndText);
m_TOCMapMenu.AddSubMenu(m_TOCLayerMenu, 5, false);

m_TOCMapMenu.SetHook(axMapControl1);
复制代码

 

第三步:TOCControl 的 MouseDown 事件:

复制代码
private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
{
    esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemNone;
    IBasicMap map = null;
    ILayer layer = null;
    object other = null;
    object index = null;

    axTOCControl1.HitTest(e.x, e.y, ref item, ref map, ref layer, ref other, ref index);

    if (e.button == 2)
    {
        if (item == esriTOCControlItem.esriTOCControlItemMap)
        {
            axTOCControl1.SelectItem(map, null);
            m_TOCMapMenu.PopupMenu(e.x, e.y, axTOCControl1.hWnd);
        }
    }
}
复制代码

 

实现效果如下:

public int AddItem (
    object item,
    int SubType,
    int index,
    bool beginGroup,
    esriCommandStyles Style
);

第一个参数:菜单项的内容,功能实现。
第二个参数:对于一个工具定义多个 type 的时候,才会用到,每一个 int 代表一个新的实现。
第三个参数:索引值,在菜单项上面显示的位置。默认为 -1,按书写顺序排序。
第四个参数:是否开始一个新组,就是在其上面有一个“——”的效果。
第五个参数:显示样式。

用 SubType 实现:

首先:建立工具,这个时候类不仅要继承 BaseCommand 类,还要继承 ICommandSubType 接口

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

            ╔════════╗
╠════╣    第1A个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● ICommandSubType 接口

 

  Provides access to members that define a subtyped command.

  Members

 

  Description
Method GetCount The number of commands defined with this CLSID.
Method SetSubType The subtype of the command.

 

复制代码
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.SystemUI;

namespace ESRI_01
{
    /// <summary>
    /// Summary description for ScaleThresholdCmd.
    /// </summary>
    [Guid("41b9d7ee-ba25-47d1-9644-f9eca4243c34")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("ESRI_01.ScaleThresholdCmd")]
    public sealed class ScaleThresholdCmd : BaseCommand, ICommandSubType  //要多继承一个接口!
    {
        #region COM Registration Function(s)
        [ComRegisterFunction()]
        [ComVisible(false)]
        static void RegisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryRegistration(registerType);

            //
            // TODO: Add any COM registration code here
            //
        }

        [ComUnregisterFunction()]
        [ComVisible(false)]
        static void UnregisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryUnregistration(registerType);

            //
            // TODO: Add any COM unregistration code here
            //
        }

        #region ArcGIS Component Category Registrar generated code
        /// <summary>
        /// Required method for ArcGIS Component Category registration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryRegistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            ControlsCommands.Register(regKey);

        }
        /// <summary>
        /// Required method for ArcGIS Component Category unregistration -
        /// Do not modify the contents of this method with the code editor.
        /// </summary>
        private static void ArcGISCategoryUnregistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            ControlsCommands.Unregister(regKey);

        }

        #endregion
        #endregion

        private IHookHelper m_hookHelper;
        private IMapControl4 m_mapControl;
        private long m_subType;    //用来分类的

        public ScaleThresholdCmd()
        {
        }

        #region Overriden Class Methods  //重写的方法

        /// <summary>
        /// Occurs when this command is created
        /// </summary>
        /// <param name="hook">Instance of the application</param>
        /// 

        public override string Caption  //重写标题
        {
            get
            {
                if (m_subType == 1)
                {
                    return "设置最大显示比例尺";
                }
                else if (m_subType == 2)
                {
                    return "设置最小显示比例尺";
                }
                else
                {
                    return "取消比例尺显示限制";
                }
            }
        }

        public override bool Enabled  //重写 Enabled 属性
        {
            get
            {
                bool enabled = true;    //默认情况下都是 true 的
                ILayer layer = (ILayer)m_mapControl.CustomProperty;  //获取所指的 layer,在 MouseDown 事件中有获取到这个 layer。

                if (m_subType == 3)  //如果选择的是 3,且最大和最小比例尺都没有设置,则为 false!
                {
                    if ((layer.MaximumScale == 0) && (layer.MinimumScale == 0))
                    {
                        enabled = false;
                    }
                }
                return enabled;
            }
        }

        public override void OnCreate(object hook)  //重写创建方法
        {
            if (hook is IMapControl4)
                m_mapControl = (IMapControl4)hook;  //给 m_mapControl 赋值
        }

        /// <summary>
        /// Occurs when this command is clicked
        /// </summary>
        public override void OnClick()  //重写单击方法
        {
            // TODO: Add ScaleThresholdCmd.OnClick implementation
            IMap map = m_mapControl.Map;
            ILayer layer = m_mapControl.CustomProperty as ILayer;
            if (m_subType == 1)
            {
                layer.MaximumScale = map.MapScale;  //为 1 的时候,实现最大显示比例尺
            }
            else if (m_subType == 2)
            {
                layer.MinimumScale = map.MapScale;  //为 2 的时候,实现最小显示比例尺
            }
            else if (m_subType == 3)
            {
                layer.MaximumScale = 0;    //为 3 的时候,去除这些
                layer.MinimumScale = 0;
            }
        }

        #endregion

        #region ICommandSubType 成员  //继承接口的话,就一定要实现接口了!

        public int GetCount()    //重写 ICommandSubType 的 GetCount 方法
        {
            return 3;
        }

        public void SetSubType(int SubType)  //重写 ICommandSubType 的 SetSubType 方法
        {
            m_subType = SubType;
        }

        #endregion
    }
}
复制代码

 

最后通过下面的 1、2、3 来实现即可!

m_TOCLayerMenu.AddItem(new ScaleThresholdCmd(), 1, 2, true, esriCommandStyles.esriCommandStyleTextOnly);
m_TOCLayerMenu.AddItem(new ScaleThresholdCmd(), 2, 3, false, esriCommandStyles.esriCommandStyleTextOnly);
m_TOCLayerMenu.AddItem(new ScaleThresholdCmd(), 3, 4, false, esriCommandStyles.esriCommandStyleTextOnly);
m_TOCLayerMenu.SetHook(axMapControl1);

 

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

            ╔════════╗
╠════╣    第2A个    ╠══════════════════════════════════════════════════╣
            ╚════════╝

●·● IToolbarMenu 接口

  Description
Method AddItem Adds an item to the ToolbarMenu.
Method AddSubMenu Adds a sub-menu to the ToolbarMenu.
Read/write property Bitmap The bitmap that is used as the icon on this ToolbarMenu.
Read/write property Caption The caption used by the ToolbarMenu.
Read/write property CommandPool The CommandPool used by the ToolbarMenu.
Read-only property Count The number of items on the ToolbarMenu.
Method Find Returns the index of the first item containing the given command or menu. Returns -1 if it is not found.
Method GetItem Returns the item at the specified index from the ToolbarMenu.
Method GetMenuDef Returns the menu definition, this method is obsolete.
Read-only property Hook The object that is passed as a hook to the OnCreate event of each item's command.
Method MoveItem Moves an item from one index to another.
Method PopupMenu Pops up the menu at the position specified.
Method Remove Removes the item at the specified index from the ToolbarMenu.
Method RemoveAll Removes all items from the ToolbarMenu.
Method SetHook Sets the object that is passed as a hook to the OnCreate event of each item's command.

posted on   McDelfino  阅读(2413)  评论(10编辑  收藏  举报

编辑推荐:
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
点击右上角即可分享
微信分享提示