先附上代码
namespace Create_PopUp_ToolbarMenu_Sample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// 调用了 ArcGIS Snippet
#region"Create PopUp ToolbarMenu"
// ArcGIS Snippet Title:
// Create PopUp ToolbarMenu
//
// Long Description:
// Stub code for creating a popup or context menu.
//
// Add the following references to the project:
// ESRI.ArcGIS.Controls
// ESRI.ArcGIS.System
// ESRI.ArcGIS.SystemUI
//
// Intended ArcGIS Products for this snippet:
// ArcGIS Engine
//
// Applicable ArcGIS Product Versions:
// 9.2
// 9.3
// 9.3.1
// 10.0
//
// Required ArcGIS Extensions:
// (NONE)
//
// Notes:
// This snippet is intended to be inserted inside a Method.
// It is not intended to be added to the base level of the Class.
//
/// <summary>
/// Member variable for the ToolbarMenu.
/// </summary>
/// <remarks>This snippet assumes a ToolbarControl has a MapControl, PageLayoutControl GlobeControl
/// or SceneControl buddy set.</remarks>
public ESRI.ArcGIS.Controls.IToolbarMenu m_ToolbarMenu;
/// <summary>
/// Create the ToolbarMenu.
/// </summary>
/// <param name="toolbarControl"></param>
/// <remarks>
/// Call to create a ToolbarMenu. For example, if a ToolbarControl
/// named AxToolbarControl1 exists use the following code:
/// CreateToolbarMenu(AxToolbarControl1.Object)
/// </remarks>
public void CreateToolbarMenu(ESRI.ArcGIS.Controls.IToolbarControl toolbarControl)
{
// Create a new ToolbarMenu
m_ToolbarMenu = new ESRI.ArcGIS.Controls.ToolbarMenuClass();
// Share the ToolbarControl's command pool
m_ToolbarMenu.CommandPool = toolbarControl.CommandPool;
// Set the hook
m_ToolbarMenu.SetHook(toolbarControl.Buddy);
// Add commands items to the ToolbarMenu.
// Add additional commands based on the mapping control being used
// For a listing of the ArcGIS Engine Controls CLSID or ProgID see: ms-help://MS.VSCC.v80/MS.VSIPCC.v80/ESRI.EDNv9.2/NET_Engine/shared/reference/guids_ctrls_cmds.htm
m_ToolbarMenu.AddItem("esriControls.ControlsAddDataCommand", -1, -1, false, ESRI.ArcGIS.SystemUI.esriCommandStyles.esriCommandStyleIconOnly);
}
/// <summary>
/// Open the Context Menu popup for the ToolbarMenu.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="hWnd"></param>
/// <remarks>
/// Call to popup the ToolbarMenu on the display of the ToolbarControl's buddy.
/// For example, if AxToolbarControl1 is buddied to AxMapControl1 use the following
/// code from one of the MapControl's mouse events:
/// PopupToolbarMenu(e.x, e.y, AxMapControl1.hWnd)
/// </remarks>
public void PopupToolbarMenu(System.Int32 x, System.Int32 y, System.Int32 hWnd)
{
m_ToolbarMenu.PopupMenu(x, y, hWnd);
}
#endregion
private void axMapControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e)
{
PopupToolbarMenu(e.x, e.y, axMapControl1.hWnd);
}
private void Form1_Load(object sender, EventArgs e)
{
CreateToolbarMenu(axToolbarControl1.Object as IToolbarControl);
}
}
}
以及窗口的主题设计
运行结果,发现工具栏以及右键快捷菜单工具栏中的工具都是灰的无法使用。
通过查看帮助 IToolbarMenu.SetHook Method
里面有这样的描述:
The Hook is a shortcut to ICommandPoolEdit::Hook on the CommandPool. If the ToolbarMenu is an item on the ToolbarControl the Hook is shared and initialized by the ToolbarControl. If the ToolbarMenu is a standalone popup menu use the SetHook method, and optionally share the CommandPool with an existing one within the application.
后面一句话说出了原因,如果是弹出菜单调用了 SetHook 方法,会改变共享池的 Hook。
以及帮助中写到
Once a command or tool has been added to the ToolbarControl, the ToolbarControl passes the hook to the OnCreate method.
默认工具栏中直接添加的工具的 Hook 是绑定到 ToolbarControl 上的
相当于调用每个工具 ICommand.OnCreate(axToolbarControl)
现在的情况是
- 弹出菜单(popup menu)和工具条(toolbar control)共享了一个命令池(command pool)
- 设置了弹出菜单(popup menu)的 Hook 为 mapControl,使得整个命令池(command pool)的 Hook 变为了 mapControl
- 导致 toolbar 中的工具不处于 OnCreate 状态
解决方法:
- 方法一:通过 CommandPool 引用对象跳转到 ICommandPoolEdit 接口,调用 CallOnCreate 接口,使工具栏上工具处于 OnCreate 状态
ICommand command = commandpool.get_Command(0);
ICommandPoolEdit pooledit = commandpool as ICommandPoolEdit;
pooledit.CallOnCreate(command);
方法二:直接 SetHook 方法直接传入 ToolBarControl.Object 对象,不改变 Hook 对象
m_ToolbarMenu.SetHook(axMapControl1.Object);