简体   繁体   中英

Debugger Visualizer Winform ToolStripDropDownMenu ComboBox only shows items when first shown

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.

Like this:

在此处输入图像描述

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);
    }
}

Then the visualizer code is simply:

public class MyVisualizer : DialogDebuggerVisualizer
{
    protected override void Show(
        IDialogVisualizerService windowService,
        IVisualizerObjectProvider objectProvider)
    {
        windowService.ShowDialog(
            new MyVisualizerDialog());
    }
}

Some extra details:

  • If I add the ToolStripComboBox to ToolStripMenuItem.DropDownItems , it works fine - it seems to specifically be an issue with having a ToolStripComboBox in a ToolStripDropDown .

  • If I create and open multiple instances of the same form class in a console app, it works fine.

  • Once the issue occurs, it keeps occurring - even when I revert the code to the version without the ToolStripDropDown

  • If I restart Visual Studio, it works the first time the form is shown, then not afterwards.

Any ideas?! Anyone know some wrinkle in the way the IDialogVisualizerService disposes controls or something?!

Thanks for reading:)

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();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM