1

我有一个 Visual Studio 调试器可视化项目,当我将 a 添加ToolStripComboBox到 aToolStripDropDownMenu时,组合框的项目仅在第一次显示表单时出现。

像这样:

在此处输入图像描述

显示问题的最基本版本的 winform 代码如下:

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

一些额外的细节:

  • 如果我添加ToolStripComboBoxToolStripMenuItem.DropDownItems,它工作正常 - 它似乎特别是在 aToolStripComboBox中有一个问题ToolStripDropDown

  • 如果我在控制台应用程序中创建并打开同一表单类的多个实例,它工作正常。

  • 一旦问题发生,它就会不断发生 - 即使我将代码恢复到没有ToolStripDropDown

  • 如果我重新启动 Visual Studio,它会在第一次显示表单时工作,然后就不行了。

有任何想法吗?!IDialogVisualizerService任何人都知道处理控件或其他方式的一些皱纹?!

谢谢阅读 :)

4

1 回答 1

2

看来,当调试器可视化器关闭时 - 这是在调试器端处理的,而不是在调试器端 - DropDown 被破坏但ToolStripManager不知道它,它发现自己有一个它不知道的无效句柄t 知道如何管理。

由于 ToolStripManager 在设计模式下也处于活动状态,这会将问题传播到整个设计器界面:您可能会发现在关闭调试器可视化器后某些 DropDown 项仍然有效,但您可能无法在任何地方添加其他 ToolStripComboBox 项。
如果你坚持,那些看起来工作的也可能不再工作。

请注意,这种不当行为可以转化为 ComboBox 对象;不是直接的,而是当您尝试通过界面访问他们的 Items 集合时。
它还可能会阻止项目编译。

显式处理在调试器可视化器端创建的 Form 对象,可以部分解决被调试者端的问题,但事实证明,在调试器可视化器端不能解决问题。

一个简单的解决方案是避免设置 ToolStripMenuItem 的 DropDown 对象,而是使用 MenuStrip,将项目添加到 ToolStripDownDown。


创建自定义数据可视化工具 可视
化工具安全注意事项


示例调试器可视化器(简单的图像可视化器)来测试好的坏的行为。

▶ 创建一个类库项目,Target Framework设置为.Net Framework, AnyCPUprofile。

[Visual Studio install Path]\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.DebuggerVisualizers.dll▶ 添加对和的引用System.Windows.Forms

▶ 将 .dll 编译为Release.

▶ 将 .dll 复制到\Common7\Packages\Debugger\Visualizers当前 Visual Studio 安装路径的目录中。

▶ 启动调试会话,在设置​​/加载图像/位图属性的位置添加断点,并使用放大镜工具打开预览。

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();
        }
    }
}
于 2020-05-08T22:30:49.563 回答