问题描述
我有一个 Visual Studio 调试器可视化项目,当我将 ToolStripComboBox
添加到 ToolStripDropDownMenu
时,组合框的项目仅在第一次显示表单时出现.
I have a Visual Studio debugger visualizer project, and when I add a ToolStripComboBox
to a ToolStripDropDownMenu
, the combobox's items only appear the first time the form is shown.
像这样:
显示问题的最基本版本的winform代码是这样的:
The most basic version of the winform code showing the issue is this:
public class MyVisualizerDialog : Form
{
public MyVisualizerDialog()
{
var toolStripComboBox = new ToolStripComboBox
{
Items = { "One", "Two", "Three" }
};
var toolStripDownDown = new ToolStripDropDownMenu
{
Items = { toolStripComboBox }
};
var toolStrip = new ToolStrip
{
Items =
{
new ToolStripMenuItem("Options")
{
DropDown = toolStripDownDown
}
}
};
Controls.Add(toolStrip);
}
}
那么可视化代码就是:
public class MyVisualizer : DialogDebuggerVisualizer
{
protected override void Show(
IDialogVisualizerService windowService,
IVisualizerObjectProvider objectProvider)
{
windowService.ShowDialog(
new MyVisualizerDialog());
}
}
一些额外的细节:
如果我将
ToolStripComboBox
添加到ToolStripMenuItem.DropDownItems
,它可以正常工作 - 这似乎是具有ToolStripComboBox
的具体问题code> 在ToolStripDropDown
中.
If I add the
ToolStripComboBox
toToolStripMenuItem.DropDownItems
, it works fine - it seems to specifically be an issue with having aToolStripComboBox
in aToolStripDropDown
.
如果我在控制台应用程序中创建并打开同一个表单类的多个实例,它工作正常.
If I create and open multiple instances of the same form class in a console app, it works fine.
一旦问题发生,它就会继续发生 - 即使我将代码恢复到没有 ToolStripDropDown
Once the issue occurs, it keeps occurring - even when I revert the code to the version without the ToolStripDropDown
如果我重新启动 Visual Studio,它会在第一次显示表单时工作,之后就不会了.
If I restart Visual Studio, it works the first time the form is shown, then not afterwards.
有什么想法吗?!任何人都知道 IDialogVisualizerService
处理控件的方式有什么问题吗?!
Any ideas?! Anyone know some wrinkle in the way the IDialogVisualizerService
disposes controls or something?!
感谢阅读:)
推荐答案
看来,当调试器可视化器关闭时 - 在调试器端处理,而不是在调试器端处理 - DropDown 被销毁,但 ToolStripManager 不知道它,它发现本身带有一个不知道如何管理的无效句柄.
It appears that, when the debugger visualizer is closed - which is handled in the debugger side, not in the debuggee side - the DropDown is destroyed but the ToolStripManager doesn't know about it and it finds itself with an invalid handle that it doesn't know how to manage.
由于 ToolStripManager 在设计模式下也处于活动状态,这会在整个设计器界面中传播问题:您可能会发现在调试器可视化器关闭后某些 DropDown 项目仍然有效,但您可能无法添加其他 ToolStripComboBox 项目任何地方.
如果你坚持,那些看似有效的方法也可能不再有效.
Since the ToolStripManager is also active in design mode, this propagates the problem throughout the designer interface: you may find that some DropDown items still work after the debugger visualizer has been closed, but you may not be able to add other ToolStripComboBox items anywhere.
If you insist, also those that appeared to be working may not work anymore.
请注意,这种不当行为可以转化为 ComboBox 对象;不是直接,而是当您尝试通过界面访问他们的 Items 集合时.
它还可能会阻止项目编译.
Note that this misbehavior can translate to ComboBox objects; not directly, but when you try to access their Items collection through the interface.
It may also prevent the Project from compiling.
显式处理在调试器可视化器端创建的 Form 对象,可以部分解决被调试器端的问题,但事实证明,在调试器可视化器端无法解决.
Explicitly disposing of the Form object created in the debugger visualizer side, can partially solve the problem on the debuggee side, but not, as it turns out, on the debugger visualizer side.
一个简单的解决方案是避免设置 ToolStripMenuItem 的 DropDown 对象,而是使用 MenuStrip,将 Items 添加到 ToolStripDownDown.
A simple solution is to avoid setting the DropDown object of a ToolStripMenuItem and use a MenuStrip instead, adding Items to a ToolStripDownDown.
示例调试器可视化工具(简单的图像可视化工具)来测试 好的 和坏的 行为.
Sample debugger visualizer (simple Image visualizer) to test the good and bad behavior.
▶ 创建一个类库项目,Target Framework
设置为.Net Framework
,AnyCPU
配置文件.
▶ Create a Class Library Project, Target Framework
set to .Net Framework
, AnyCPU
profile.
▶ 添加对 [Visual Studio 安装路径]Common7IDEPublicAssembliesMicrosoft.VisualStudio.DebuggerVisualizers.dll
和 System.Windows.Forms
的引用.
▶ Add a reference to [Visual Studio install Path]Common7IDEPublicAssembliesMicrosoft.VisualStudio.DebuggerVisualizers.dll
and System.Windows.Forms
.
▶ 将 .dll 编译为 Release
.
▶ Compile the .dll as Release
.
▶ 将 .dll 复制到当前 Visual Studio 安装路径的 Common7PackagesDebuggerVisualizers
目录.
▶ Copy the .dll to the Common7PackagesDebuggerVisualizers
directory of your current Visual Studio installation path.
▶ 启动调试会话,在设置/加载图像/位图属性的位置添加断点,然后使用放大镜工具打开预览.
▶ Start a debug session, add a breakpoint where an Image/Bitmap property is set/loaded and use the magnifier tool to open a preview.
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.VisualStudio.DebuggerVisualizers;
[assembly: DebuggerVisualizer(
typeof(ImageVisualizer.DebuggerSide),
typeof(VisualizerObjectSource), Target = typeof(Image), Description = "Test Visualizer")]
namespace TestVisualizer
{
public class DebuggerSide : DialogDebuggerVisualizer
{
override protected void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
{
var image = (Image)objectProvider.GetObject();
var form = new Form();
form.ClientSize = new Size(image.Width, image.Height);
form.FormBorderStyle = FormBorderStyle.FixedSingle;
form.SuspendLayout();
// ------- WORKING CODE ---------------
var menuStrip = new MenuStrip() { };
var tsComboBox = new ToolStripComboBox { Items = { "One", "Two", "Three" } };
var toolStripDownDown = new ToolStripMenuItem() { Text = "Options" };
toolStripDownDown.DropDownItems.AddRange(new ToolStripItem[] { tsComboBox });
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripDownDown });
// ------- WORKING CODE ---------------
// ------- BAD CODE ---------------
//var toolStripComboBox = new ToolStripComboBox { Items = { "One", "Two", "Three" } };
//var toolStripDownDown = new ToolStripDropDownMenu { Items = { toolStripComboBox } };
//var toolStrip = new ToolStrip {
// Items = { new ToolStripMenuItem("Options") { DropDown = toolStripDownDown } }
//};
// ------- BAD CODE ---------------
var pBox = new PictureBox() { Image = image, Dock = DockStyle.Fill };
//form.Controls.Add(toolStrip);
form.Controls.Add(menuStrip);
form.Controls.Add(pBox);
form.MainMenuStrip = menuStrip;
form.ResumeLayout(false);
form.PerformLayout();
windowService.ShowDialog(form);
form?.Dispose();
}
}
}
这篇关于Debugger Visualizer Winform ToolStripDropDownMenu ComboBox 仅在首次显示时显示项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!