本帖最后由 transteel 于 2025-8-5 23:20 编辑
想用.net实现一个跟随鼠标的菜单代替PromptStringOptions,查了一些资料没找到。哪位大神有例子吗?或者有个思路也行。
感谢惊惊的指导,借助AI提示,基本上实现了(虽然还有bug),效果和代码如下:

网友答:
它这个应该只是关键字...你看看getstring参数上面的配置里面是不是有网友答: 本帖最后由 箭头_Row 于 2025-8-13 12:29 编辑
看動圖大致是下面步驟操作:
第一步獲取座標點,判斷操作:
option:點取點則進行接下來插入操作
option:點右鍵則進行右鍵菜單(關鍵字菜單)選取關鍵字操作
{
根據關鍵寫對應的更改參數的邏輯;
}
注意:獲取點時一定要打開可空輸入!
大致代碼如下:


感謝驚驚提示的源碼及思路:獲取關鍵字字典。


网友答:
问了下chatgpt大概实现了(虽然还有bug):

网友答: 跟随鼠标的菜单指的是什么情况下使用的。网友答: 本帖最后由 你有种再说一遍 于 2025-8-5 22:44 编辑
你要说场景才行,e大曾经做过一个图标跟随在鼠标旁边.
我的场景例子是拉伸填充:
CAD夹点触发时候,没有提供坐标点,我就无法获取位于那个多段线上面.
然后我用鼠标钩子一直更新一个静态字段,一旦夹点触发了,我就可以读取静态字段屏幕坐标转为CAD模型坐标了.
相关代码写在IFox的jing分支网友答:
实现下面的通过命令行获取输入值的功能:

网友答:
那你是想关键字时候触发自定义右键菜单,然后可以亮显其中选项?网友答:
场景:画直线,选择直线的终点前需要确定线型,目前的实现方式是键入一个数字来判断选择的是哪个线型,也可以使用右键菜单来选择。我想要实现一个跟随鼠标的菜单(选择直线起点后,这个菜单就出现并跟随鼠标移动),代替键入数字确定线型。(下图是右键菜单)
网友答:
那你不应该用右键菜单,要用非模态面板去做.
也就是此时此刻你虽然触发了"右键"但是你钩子拦截了"右键"唤起了"面板"网友答:
我好像没有说清楚……原谅我的语言匮乏!待我找到个示意动图再来请教!网友答:
找到动图示例了:
想用.net实现一个跟随鼠标的菜单代替PromptStringOptions,查了一些资料没找到。哪位大神有例子吗?或者有个思路也行。
感谢惊惊的指导,借助AI提示,基本上实现了(虽然还有bug),效果和代码如下:

- Dim promptString As New PromptKeywordOptions(vbCrLf & $"选择管线类型(根据提示输入数字)[SC×1(1)/SC×2(2)/SC×4(3)/SC×6(4)/PE×1(5)/PE×2(6)/PE×4(7)/PE×6(8)/]<{typeindex}>")
- promptString.Keywords.Add("SC×1", "1")
- promptString.Keywords.Add("SC×2", "2")
- promptString.Keywords.Add("SC×4", "3")
- promptString.Keywords.Add("SC×6", "4")
- promptString.Keywords.Add("PE×1", "5")
- promptString.Keywords.Add("PE×2", "6")
- promptString.Keywords.Add("PE×4", "7")
- promptString.Keywords.Add("PE×6", "8")
- ' 获取用户选择的选项
- Dim result As PromptResult = ed.GetKeywords(promptString)
- If result.Status = PromptStatus.OK Then
- ' 通过选项设置 typeindex
- typeindex = CInt(result.StringResult)
- End If
网友答:
transteel 发表于 2025-8-5 23:04
找到动图示例了:
它这个应该只是关键字...你看看getstring参数上面的配置里面是不是有网友答: 本帖最后由 箭头_Row 于 2025-8-13 12:29 编辑
看動圖大致是下面步驟操作:
第一步獲取座標點,判斷操作:
option:點取點則進行接下來插入操作
option:點右鍵則進行右鍵菜單(關鍵字菜單)選取關鍵字操作
{
根據關鍵寫對應的更改參數的邏輯;
}
注意:獲取點時一定要打開可空輸入!
大致代碼如下:

- public static class CsTest
- {
- private enum Keywords
- {
- [Description("A")]
- 轴类,
- [Description("S")]
- 设置,
- }
- [CommandMethod(nameof(Dg))]
- public static void Dg()
- {
- using var doc = Acaop.DocumentManager.MdiActiveDocument;
- var ed = doc.Editor;
- // 以下測試代碼,循環可自行擴展
- PromptPointOptions ppo = new("\n指定第一个点");
- ppo.AllowNone = true; // 打开可空才會右鍵彈關鍵字菜單
- PromptPointResult ppr = Env.Editor.GetPoint(ppo);
- if (ppr.Status == PromptStatus.None)
- {
- PromptKeywordOptions options = new(string.Empty);
- var keywordsMap = ArEnumEx.GetKeywordsMap<Keywords>();
- options.AddKeywords([.. keywordsMap.Keys]);
- options.AppendKeywordsToMessage = false; //不将关键字列表添加到提示信息中
- options.Message = "\n右鍵彈出菜單示例" + keywordsMap.ToMessage();
- PromptResult pr = ed.GetKeywords(options);
- if (pr.Status.CancelPrint())
- return;
- // 進行更改參數的操作
- }
- else if (ppr.Status != PromptStatus.OK)
- return;
- Point3d ptStart = ppr.Value;
- }
- }

- /// <summary>
- /// 獲取關鍵字字典
- /// </summary>
- /// <typeparam name="T">關鍵字枚舉</typeparam>
- /// <returns> Dictionary 快捷鍵,(描述字_中文,Enum值)</returns>
- public static Dictionary<string, (string Key_CN, T enumValue)> GetKeywordsMap<T>()
- where T : Enum
- {
- Dictionary<string, (string, T)> keywordsDic = [];
- var type = typeof(T);
- var typeDesc = typeof(DescriptionAttribute);
- foreach (var e in Enum.GetValues(type))
- {
- var name = e.ToString();
- object objArr = type.GetField(name).GetCustomAttributes(typeDesc, true)[0];
- keywordsDic.Add(((DescriptionAttribute)objArr).Description, (name, (T)e));
- }
- return keywordsDic;
- }
感謝驚驚提示的源碼及思路:獲取關鍵字字典。

- /// <summary>
- /// 获取关键字提示信息行。
- /// </summary>
- /// <param name="keywordsDic">keywords關鍵字字典</typeparam>
- /// <param name="defaultKeyword">可选的默认关键字,非空时添加到结果中</param>
- /// <returns> 返回格式示例:[字典(D)/板厚(T)/层高(H)/完成面(F)/图层(C)]</returns>
- public static StringBuilder ToMessage<T>(
- this Dictionary<string, (string Key_CN, T enumValue)> keywordsDic,
- string defaultKeyword = ""
- )
- where T : Enum
- {
- int number = 0;
- StringBuilder keywordNotice = new("[");
- foreach (var item in keywordsDic)
- {
- keywordNotice.Append(item.Value.Key_CN);
- keywordNotice.Append('(');
- keywordNotice.Append(item.Key);
- keywordNotice.Append(')');
- if (number < keywordsDic.Count - 1)
- keywordNotice.Append('/');
- number++;
- }
- keywordNotice.Append(']');
- if (defaultKeyword != string.Empty)
- if (keywordsDic.ContainsKey(defaultKeyword))
- keywordNotice.Append($"<{defaultKeyword}>");
- else // 無默認值時報錯提示
- throw new ArgumentException("错误的默认值!");
- return keywordNotice;
- }

- /// <summary>
- /// 檢查提示狀態是否為取消狀態,如果是則打印指定消息並返回 true。
- /// </summary>
- /// <param name="status">提示狀態。</param>
- /// <param name="message">要打印的消息,默認為 "*取消*"。</param>
- /// <returns>如果提示狀態不是 OK,則返回 true,否則返回 false。</returns>
- public static bool CancelPrint(this PromptStatus status, string message = "*取消*")
- {
- if (status == PromptStatus.OK)
- return false;
- message.Print();
- return true;
- }
网友答:
你有种再说一遍 发表于 2025-8-5 23:10
它这个应该只是关键字...你看看getstring参数上面的配置里面是不是有
问了下chatgpt大概实现了(虽然还有bug):

- Dim promptString As New PromptKeywordOptions(vbCrLf & $"选择管线类型(根据提示输入数字)[SC×1(1)/SC×2(2)/SC×4(3)/SC×6(4)/PE×1(5)/PE×2(6)/PE×4(7)/PE×6(8)/]<{typeindex}>")
- promptString.Keywords.Add("SC×1", "1")
- promptString.Keywords.Add("SC×2", "2")
- promptString.Keywords.Add("SC×4", "3")
- promptString.Keywords.Add("SC×6", "4")
- promptString.Keywords.Add("PE×1", "5")
- promptString.Keywords.Add("PE×2", "6")
- promptString.Keywords.Add("PE×4", "7")
- promptString.Keywords.Add("PE×6", "8")
- ' 获取用户选择的选项
- Dim result As PromptResult = ed.GetKeywords(promptString)
- If result.Status = PromptStatus.OK Then
- ' 通过选项设置 typeindex
- typeindex = CInt(result.StringResult)
- End If
网友答: 跟随鼠标的菜单指的是什么情况下使用的。网友答: 本帖最后由 你有种再说一遍 于 2025-8-5 22:44 编辑
你要说场景才行,e大曾经做过一个图标跟随在鼠标旁边.
我的场景例子是拉伸填充:
CAD夹点触发时候,没有提供坐标点,我就无法获取位于那个多段线上面.
然后我用鼠标钩子一直更新一个静态字段,一旦夹点触发了,我就可以读取静态字段屏幕坐标转为CAD模型坐标了.
相关代码写在IFox的jing分支网友答:
edata 发表于 2025-8-5 22:13
跟随鼠标的菜单指的是什么情况下使用的。
实现下面的通过命令行获取输入值的功能:

- Dim promptstring As New PromptStringOptions(vbCrLf & $"选择管线类型(根据提示输入数字)[SC×1(1)/SC×2(2)/SC×4(3)/SC×6(4)/PE×1(5)/PE×2(6)/PE×4(7)/PE×6(8)/]<{typeindex}>")
- Dim sr As PromptResult = ed.getstring(promptstring)
网友答:
transteel 发表于 2025-8-5 22:44
实现下面的通过命令行获取输入值的功能:
那你是想关键字时候触发自定义右键菜单,然后可以亮显其中选项?网友答:
你有种再说一遍 发表于 2025-8-5 22:42
你要说场景才行,e大曾经做过一个图标跟随在鼠标旁边.
我的场景例子是拉伸填充:
场景:画直线,选择直线的终点前需要确定线型,目前的实现方式是键入一个数字来判断选择的是哪个线型,也可以使用右键菜单来选择。我想要实现一个跟随鼠标的菜单(选择直线起点后,这个菜单就出现并跟随鼠标移动),代替键入数字确定线型。(下图是右键菜单)
网友答:
transteel 发表于 2025-8-5 22:48
场景:画直线,选择直线的终点前需要确定线型,目前的实现方式是键入一个数字来判断选择的是哪个线型,也 ...
那你不应该用右键菜单,要用非模态面板去做.
也就是此时此刻你虽然触发了"右键"但是你钩子拦截了"右键"唤起了"面板"网友答:
你有种再说一遍 发表于 2025-8-5 22:52
那你不应该用右键菜单,要用非模态面板去做.
也就是此时此刻你虽然触发了"右键"但是你钩子拦截了"右键"唤 ...
我好像没有说清楚……原谅我的语言匮乏!待我找到个示意动图再来请教!网友答:
你有种再说一遍 发表于 2025-8-5 22:52
那你不应该用右键菜单,要用非模态面板去做.
也就是此时此刻你虽然触发了"右键"但是你钩子拦截了"右键"唤 ...
找到动图示例了: