Debugger Visualizer Winform ToolStripDropDownMenu ComboBox only shows items when first shown

蓝咒 提交于 2020-05-31 03:27:11

问题


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 :)


回答1:


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


来源:https://stackoverflow.com/questions/61675774/debugger-visualizer-winform-toolstripdropdownmenu-combobox-only-shows-items-when

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!