ArcEngine开发过程中遇到axToolbarControl添加item变灰无法使用的解决方法总结

本文介绍了一种解决ArcGIS开发中工具栏按钮失效的问题。通过在窗体加载时用代码手动添加按钮来激活其功能,如全图刷新等。提供了一种实用的开发技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近期基于AE做个小系统的开发 使用axToolbarControl与axMapControl绑定开发时,运行过后只有添加文件和保存两个按钮处于有效,而其他按钮处于失效(灰色)状态

具体原因还未清楚,但是已找到解决办法与大家共享

办法是 在窗体load的时通过代码添加具体的按钮:

比如全图刷新按钮的添加方式:

 ICommand command = new ControlsMapFullExtentCommandClass();
 axToolbarControl1.AddItem(command, -1, -1, false, 0, esriCommandStyles.esriCommandStyleIconOnly);

除此之外还有其他几种方式,此处不再详列。

<think>我们正在解决ArcEngine 10.2中设置axToolbarControlItem文本为中文显示失败的问题。根据之前的讨论,我们尝试了两种方法:动态设置文本和自定义命令类。但是用户在实际操作中可能遇到文本设置后显示的问题。因此,我们需要深入分析可能的原因并提供解决方案。 可能的原因及解决方案: 1. **文本显示样式未设置**:axToolbarControl默认可能只显示图标,显示文本。需要设置工具栏的显示样式包含文本。 2. **自动隐藏文本**:工具栏可能设置为自动隐藏文本(例如,当空间足时隐藏文本),需要关闭自动隐藏。 3. **项宽度足**:如果项的宽度足以显示文本,文本可能被截断或隐藏。需要调整项宽度。 4. **命令项文本属性设置时机当**:可能在工具栏初始化之前或之后设置文本,导致被覆盖。建议在工具栏加载完成后设置(例如在OnCreate事件中)。 5. **资源绑定问题**:确保在程序启动时正确绑定ArcGIS产品(Engine或Desktop)。 具体步骤: 方法一:设置工具栏样式和文本显示(推荐首先检查) 1. 设置工具栏的文本显示样式为包含文本(如IconAndText)。 2. 关闭自动隐藏文本。 3. 调整项宽度(可选)。 方法二:在OnCreate事件中设置文本(确保设置时机正确) 由于axToolbarControl在创建时会重置一些属性,我们可以将设置文本的代码放在OnCreate事件中(如果使用自定义控件,可以在设计时设置)。 方法三:使用自定义命令类(彻底解决,但需要为每个命令创建类) 创建自定义命令类,在构造函数中直接设置中文文本,然后替换工具中的默认命令。 下面我们将详细说明这些步骤: 步骤1:设置工具栏样式 在窗体加载事件中,设置工具栏的显示样式和文本对齐方式,并关闭自动隐藏文本。 步骤2:在OnCreate事件中设置文本 由于axToolbarControl在创建时可能会重置Item的文本,因此我们可以将设置文本的代码放在axToolbarControl的OnCreate事件处理程序中。但是,axToolbarControl没有直接的OnCreate事件,我们可以使用控件的HandleCreated事件(注意:确保只执行一次,避免重复设置)。 步骤3:调整项宽度 如果文本仍然显示全,可以设置每个项的宽度。 代码示例: 我们结合方法一和方法二,在窗体加载事件中设置工具栏属性,并遍历项设置文本,同时调整项宽度。 详细代码: ```csharp private void Form1_Load(object sender, EventArgs e) { // 设置工具栏属性:显示文本和图标,文本在右侧,自动隐藏文本 axToolbarControl1.TextAlignment = ESRI.ArcGIS.Controls.toolbarTextAlignment.tbtTextRight; axToolbarControl1.AutoHideText = false; axToolbarControl1.Style = ESRI.ArcGIS.Controls.toolbarControlStyles.tbsIconAndText; // 遍历所有工具项 for (int i = 0; i < axToolbarControl1.ItemCount; i++) { ESRI.ArcGIS.SystemUI.ICommandItem cmdItem = axToolbarControl1.GetItem(i); // 根据命令ID设置中文文本 string cmdID = cmdItem.ID; switch (cmdID) { case "esriControls.ControlsMapZoomInTool": // 放大工具 cmdItem.Text = "放大"; break; case "esriControls.ControlsMapZoomOutTool": // 缩小工具 cmdItem.Text = "缩小"; break; case "esriControls.ControlsMapPanTool": // 平移工具 cmdItem.Text = "平移"; break; case "esriControls.ControlsMapFullExtentCommand": // 全图 cmdItem.Text = "全图"; break; // 添加其他需要设置的工具 default: // 对于没有匹配到的命令,保留原文本或设置为默认 // 也可以设置,跳过 break; } // 设置项宽度(根据文本长度调整,这里示例为80像素) axToolbarControl1.SetItemWidth(i, 80); } // 刷新工具axToolbarControl1.Refresh(); } ``` 如果上述方法仍然无效,可能是因为在窗体加载时,工具栏还没有完全初始化。我们可以尝试在控件的HandleCreated事件中设置,但HandleCreated事件可能被多次触发,因此需要设置一个标志位来确保只执行一次。 或者,我们可以使用一个定时器,延迟执行设置文本的操作(例如延迟100毫秒),以确保在工具栏完全初始化后再设置文本。 使用定时器的示例: ```csharp private void Form1_Load(object sender, EventArgs e) { // 设置一个单次执行的定时器,延迟100毫秒 Timer timer = new Timer(); timer.Interval = 100; timer.Tick += (s, args) => { timer.Stop(); timer.Dispose(); SetToolbarText(); }; timer.Start(); } private void SetToolbarText() { // 这里放置上面设置文本和宽度的代码 // ... 同上面Form1_Load中的代码 } ``` 方法三:自定义命令类(一劳永逸,但需要为每个命令创建类) 以平移工具为例: ```csharp public class ChinesePanTool : ESRI.ArcGIS.ADF.BaseClasses.BaseCommand { public ChinesePanTool() { base.m_caption = "平移"; // 直接设置中文文本 base.m_toolTip = "地图平移工具"; // 设置图标(可选) base.m_bitmap = Properties.Resources.PanToolIcon; // 假设资源中有图标 } public override void OnClick() { // 实现功能,这里可以调用默认的平移命令,或者自己实现 // 通常我们需要自己实现,而是希望使用原有的功能,所以我们可以创建一个原有命令的实例并调用 ESRI.ArcGIS.Controls.IMapControlDefault mapControl = null; // 需要传入MapControl // 注意:这里需要将MapControl传入自定义命令类,可以通过构造函数传入 // 例如在构造函数中传入MapControl,然后在这里使用 // 由于原有平移命令需要绑定MapControl,所以我们需要在自定义命令中保存MapControl的引用 // 具体实现略,因为需要更多的上下文 } } ``` 然后,我们需要将默认的平移工具替换为自定义命令: ```csharp // 首先移除默认的平移工具 int panIndex = -1; for (int i = 0; i < axToolbarControl1.ItemCount; i++) { ESRI.ArcGIS.SystemUI.ICommandItem cmdItem = axToolbarControl1.GetItem(i); if (cmdItem.ID == "esriControls.ControlsMapPanTool") { panIndex = i; break; } } if (panIndex != -1) axToolbarControl1.RemoveItem(panIndex); // 添加自定义平移工具 ChinesePanTool panTool = new ChinesePanTool(); // 注意:自定义命令需要绑定MapControl,这里假设在构造时已经绑定,或者通过属性设置 axToolbarControl1.AddItem(panTool, -1, -1, true, 0, ESRI.ArcGIS.SystemUI.esriCommandStyles.esriCommandStyleIconAndText); ``` 注意:自定义命令类需要正确处理与MapControl的绑定,否则无法正常工作。这可能需要更多的代码来维护。 考虑到复杂性和维护成本,如果只是需要修改文本,建议优先尝试方法一和方法二。 总结:在ArcEngine 10.2中设置axToolbarControlItem文本为中文显示失败,通常是因为显示样式、自动隐藏文本或设置时机的问题。通过设置工具栏的Style、TextAlignment和AutoHideText属性,并在正确的时机(如使用定时器延迟设置)设置每个Item的Text属性,可以解决该问题。 如果以上方法均无效,可能需要考虑使用自定义命令类来彻底替换默认命令,但这种方法较为复杂。 最后,请确保在程序启动时绑定了正确的ArcGIS产品: ```csharp public Form1() { // 在构造函数中绑定 ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop); InitializeComponent(); } ``` 希望这些方法能帮助您解决问题。 §§相关问题§§ 1. 如何为 AxToolbarControl 添加自定义图标? 2. AxToolbarControl 如何与 MapControl 实现交互操作? 3. 如何在状态栏显示地图坐标信息? 4. 如何通过代码动态启用/禁用工具栏按钮? 5. 如何实现工具栏按钮的分组和分隔符?</think>### ArcEngine 10.2 设置 axToolbarControl Item 中文显示失败解决方案 在 ArcEngine 10.2 中设置 axToolbarControlItem 文本为中文显示失败,通常是由于以下原因造成的。以下是完整的解决方案: #### 核心问题分析 1. **文本显示模式未正确设置**(最常见原因) 2. **命令项属性设置时机当** 3. **资源绑定问题** 4. **控件刷新机制未触发** #### 完整解决方案 ##### 步骤1:确保文本显示模式正确 ```csharp // 设置文本显示模式(关键!) axToolbarControl1.Style = ESRI.ArcGIS.Controls.toolbarControlStyles.tbsIconAndText; // 图标+文本 // 文本对齐方式 axToolbarControl1.TextAlignment = ESRI.ArcGIS.Controls.toolbarTextAlignment.tbtTextRight; // 文本在右侧 // 禁用自动隐藏文本 axToolbarControl1.AutoHideText = false; ``` ##### 步骤2:在正确时机设置文本属性 ```csharp private void Form1_Load(object sender, EventArgs e) { // 确保绑定ArcGIS资源 ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Engine); // 延迟设置(解决初始化时机问题) System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); timer.Interval = 100; // 100ms延迟 timer.Tick += (s, args) => { timer.Stop(); SetChineseText(); }; timer.Start(); } private void SetChineseText() { // 遍历所有工具项 for (int i = 0; i < axToolbarControl1.ItemCount; i++) { ESRI.ArcGIS.SystemUI.ICommandItem cmdItem = axToolbarControl1.GetItem(i); // 根据命令ID设置中文文本 switch (cmdItem.ID) { case "esriControls.ControlsMapZoomInTool": cmdItem.Text = "放大"; cmdItem.Caption = "放大"; // 双保险设置 break; case "esriControls.ControlsMapZoomOutTool": cmdItem.Text = "缩小"; break; case "esriControls.ControlsMapPanTool": cmdItem.Text = "平移"; break; case "esriControls.ControlsMapFullExtentCommand": cmdItem.Text = "全图"; break; case "esriControls.ControlsOpenDocCommand": cmdItem.Text = "打开地图"; break; // 添加其他工具项... } // 设置项宽度确保文本显示完整 axToolbarControl1.SetItemWidth(i, 80); } // 强制刷新控件(关键步骤!) axToolbarControl1.Refresh(); axToolbarControl1.Update(); } ``` ##### 步骤3:备用方案 - 自定义命令类 如果上述方法无效,使用自定义命令类替代默认命令: ```csharp // 自定义平移命令类 public class CustomPanCommand : ESRI.ArcGIS.ADF.BaseClasses.BaseCommand { private IMapControl4 m_mapControl; public CustomPanCommand() { base.m_caption = "平移"; // 直接设置中文 base.m_toolTip = "地图平移工具"; base.m_name = "CustomPanCommand"; } public override void OnCreate(object hook) { m_mapControl = (IMapControl4)hook; } public override void OnClick() { // 实现平移功能 m_mapControl.CurrentTool = null; m_mapControl.CurrentTool = "esriControls.ControlsMapPanTool"; } } // 在窗体中添加自定义命令 private void AddCustomCommands() { // 移除默认平移工具 RemoveItemByID("esriControls.ControlsMapPanTool"); // 添加自定义命令 CustomPanCommand panCmd = new CustomPanCommand(); axToolbarControl1.AddItem(panCmd, -1, -1, true, 0, ESRI.ArcGIS.SystemUI.esriCommandStyles.esriCommandStyleIconAndText); } private void RemoveItemByID(string itemID) { for (int i = 0; i < axToolbarControl1.ItemCount; i++) { if (axToolbarControl1.GetItem(i).ID == itemID) { axToolbarControl1.RemoveItem(i); return; } } } ``` #### 常见问题排查表 | 问题现象 | 解决方案 | |---------|---------| | 文本完全显示 | 检查`Style`是否为`tbsIconAndText` | | 中文显示为方框 | 确保系统支持中文字体,添加`axToolbarControl1.Font = new Font("微软雅黑", 9)` | | 设置后恢复英文 | 使用延迟设置或自定义命令类 | | 部分项更新 | 单独设置`axToolbarControl1.SetItem(i)`后刷新 | | 工具栏布局错乱 | 调整`SetItemWidth()`参数,增加宽度 | #### 关键注意事项 1. **资源绑定**:在窗体构造函数中必须添加: ```csharp public Form1() { ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Engine); InitializeComponent(); } ``` 2. **设计时支持**:在属性窗口中设置: - 将`AutoHideText`设为`False` - 将`TextAlignment`设为`tbtTextRight` 3. **字体设置**:如果显示乱码,添加: ```csharp axToolbarControl1.Font = new Font("Microsoft YaHei", 9); ``` 4. **刷新机制**:任何修改后必须调用: ```csharp axToolbarControl1.Refresh(); Application.DoEvents(); // 强制UI更新 ``` > **技术说明**:ArcEngine 10.2 的工具栏控件在初始化时会重置部分属性,因此延迟设置和自定义命令类是最可靠的解决方案[^3]。对于生产环境,建议采用自定义命令类方案,虽然开发量较大,但能彻底解决本地化问题[^7]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值