调试器可视化工具Winform ToolStripDropDownMenu ComboBox仅在首次显示时显示项目 [英] Debugger Visualizer Winform ToolStripDropDownMenu ComboBox only shows items when first shown

查看:143
本文介绍了调试器可视化工具Winform ToolStripDropDownMenu ComboBox仅在首次显示时显示项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



就像这样:





显示问题的winform代码的最基本版本是这样的:

 公共类MyVisualizerDialog:表单
{
public MyVisualizerDialog()
{
var toolStripComboBox = new ToolStripComboBox
{
Items = {一个,两个,三个}
};

var toolStripDownDown = new ToolStripDropDownMenu
{
Items = {toolStripComboBox}
};

var toolStrip =新的ToolStrip
{
项目=
{
new ToolStripMenuItem( Options)
{
DropDown = toolStripDownDown
}
}
};

Controls.Add(toolStrip);
}
}

然后,可视化代码很简单:

 公共类MyVisualizer:DialogDebuggerVisualizer 
{
受保护的覆盖无效Show(
IDialogVisualizerService windowService,
IVisualizerObjectProvider objectProvider)
{
windowService.ShowDialog(
new MyVisualizerDialog());
}
}

一些额外的细节:




  • 如果我将 ToolStripComboBox 添加到 ToolStripMenuItem.DropDownItems ,它工作正常-在 ToolStripDropDown 中具有 ToolStripComboBox 似乎是一个特别的问题。 / p>


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


  • 一旦发生此问题,就会发生 keeps -即使当我将代码还原为没有 ToolStripDropDown


  • 如果我重新启动Visual Studio,它将在第一次显示该窗体时起作用,然后再显示。




有什么想法吗?!任何人都知道 IDialogVisualizerService 布置控件或某些东西的方式吗?!



感谢阅读:)

解决方案

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



由于ToolStripManager在设计模式下也处于活动状态,因此这会在设计器界面中传播该问题:您可能会发现在关闭调试器可视化器后,某些DropDown项仍然有效,但您可能无法在任何地方添加其他ToolStripComboBox项。

如果您 insist ,那么那些看起来有效的东西可能不再起作用。



请注意,这种不当行为可以转换为ComboBox对象;不是直接,而是当您尝试通过界面访问其Items集合时。

这也可能会阻止Project的编译。



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



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






创建自定义数据可视化器

可视化工具安全注意事项






示例调试器可视化工具(简单的图像可视化工具),用于测试行为。



►创建一个类库项目,将 Target Framework 设置为 .Net Framework AnyCPU 配置文件。



►添加对的引用[Visual Studio安装路径] \Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.DebuggerVisualizers.dll System.Windows.Forms



►将.dll编译为 Release



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



►开始调试会话,添加一个设置/加载Image / Bitmap属性的断点,然后使用放大镜工具打开预览。

 使用System.Diagnostics; 
使用System.Drawing;
使用System.Windows.Forms;
使用Microsoft.VisualStudio.DebuggerVisualizers;

[程序集:DebuggerVisualizer(
typeof(ImageVisualizer.DebuggerSide),
typeof(VisualizerObjectSource),Target = typeof(Image),Description = Test Visualizer)]
名称空间TestVisualizer
{
公共类DebuggerSide:DialogDebuggerVisualizer
{
覆盖受保护的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();

// -------工作代码---------------
var menuStrip = new MenuStrip(){};
var tsComboBox = new ToolStripComboBox {Items = {一个,两个,三个}};
var toolStripDownDown = new ToolStripMenuItem(){文字=选项};
toolStripDownDown.DropDownItems.AddRange(new ToolStripItem [] {tsComboBox});
menuStrip.Items.AddRange(new ToolStripItem [] {toolStripDownDown});
// -------工作代码---------------

// -------错误代码- --------------
// var toolStripComboBox = new ToolStripComboBox {Items = {一个,两个,三个}};
// var toolStripDownDown = new ToolStripDropDownMenu {Items = {toolStripComboBox}};
// var toolStrip = new ToolStrip {
// Items = {new ToolStripMenuItem( Options){DropDown = toolStripDownDown}}
//};

// -------错误代码---------------

var pBox = new PictureBox(){图片=图片,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);
形式?.Dispose();
}
}
}


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

这篇关于调试器可视化工具Winform ToolStripDropDownMenu ComboBox仅在首次显示时显示项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆