I have a Visual Studio debugger visualizer project, and when I add a ToolStripComboBox
to a ToolStripDropDownMenu
, the combobox\'s items only appear th
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.
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.
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.
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.
A simple solution is to avoid setting the DropDown object of a ToolStripMenuItem and use a MenuStrip instead, adding Items to a ToolStripDownDown.
Create custom data visualizers
Visualizer Security Considerations
Sample debugger visualizer (simple Image visualizer) to test the good and bad behavior.
► Create a Class Library Project, Target Framework
set to .Net Framework
, AnyCPU
profile.
► Add a reference to [Visual Studio install Path]\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.DebuggerVisualizers.dll
and System.Windows.Forms
.
► Compile the .dll as Release
.
► Copy the .dll to the \Common7\Packages\Debugger\Visualizers
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();
}
}
}