如何在固定大小的 ToolStripDropDown 中滚动

发布于 2024-09-29 13:20:13 字数 1091 浏览 2 评论 0原文

我正在使用 ToolStripDropDown 控件来实现自定义 ComboBox 类控件的下拉部分。为了在视觉上吸引人,我在下拉菜单上施加了 MaximumSize 并手动指定其中每个 ToolStripButton 的宽度 - 结果是一个宽度相同的弹出窗口作为激活它的控件,下拉部分的高度有上限。

示例(简化):

ToolStripDropDown dropDown = new ToolStripDropDown();
dropDown.MaximumSize = new Size(200, 100);
dropDown.RenderMode = ToolStripRenderMode.System;
dropDown.AutoSize = true;

for (int i = 0; i < 50; i++) {
    ToolStripButton dropDownItem = (ToolStripButton)dropDown.Items.Add("Item " + i);
    dropDownItem.AutoSize = false;
    dropDownItem.Size = new Size(200, 20);
}

dropDown.Show(owningControl, new Point(0, owningControl.Height - 1));

如您所见,应用了对弹出窗口大小的约束,但是不显示向上/向下滚动按钮,并且似乎没有办法让它们出现。 ToolStripDropDown 中似乎没有任何关于滚动偏移或将特定项目滚动到视图中的机制(例如 上的 EnsureVisible()) ListViewItem)。

那么,我怎样才能让下拉菜单滚动呢?任何方法都足够了,无论是滚动条、滚动按钮甚至是鼠标滚轮。

(顺便说一句,我曾多次尝试使用 Form 作为下拉部分来制作类似的控件 - 尽管尝试了数十种解决方案来防止弹出窗口在单击其控件时窃取焦点或获得焦点,但这似乎我还排除了使用 ToolStripControlHost 的可能性,它的托管控件仍然可以将焦点从打开它的表单上移开。)

I am using a ToolStripDropDown control to implement the dropdown portion of a custom ComboBox-like control. In order to be visually appealing, I am imposing a MaximumSize on the dropdown and manually specifying the width of each ToolStripButton within it - the result is a popup which is the same width as the control that activates it, with a cap on the height of the height of the dropdown portion.

Example (simplified):

ToolStripDropDown dropDown = new ToolStripDropDown();
dropDown.MaximumSize = new Size(200, 100);
dropDown.RenderMode = ToolStripRenderMode.System;
dropDown.AutoSize = true;

for (int i = 0; i < 50; i++) {
    ToolStripButton dropDownItem = (ToolStripButton)dropDown.Items.Add("Item " + i);
    dropDownItem.AutoSize = false;
    dropDownItem.Size = new Size(200, 20);
}

dropDown.Show(owningControl, new Point(0, owningControl.Height - 1));

As you can see, the constraints on the popup's size are applied, however the up/down scroll buttons are not displayed and there seems to be no way to make them appear. There do not appear to be any methods or properties within ToolStripDropDown regarding the scrolling offset or a mechanism to scroll a particular item into view (such as EnsureVisible() on ListViewItem).

How, then, can I get the dropdown to scroll? Any method would be sufficient, be it a scroll bar, scroll buttons or even the mouse-wheel.

(Incidentally, I have tried many times to make similar controls using a Form for the dropdown portion - despite trying dozens of solutions to prevent the popup from stealing focus or gaining focus when its controls are clicked, this seems to be a dead end. I have also ruled out using ToolStripControlHost, whose hosted control can still take focus away from the form that opened it.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

残花月 2024-10-06 13:20:13

终于破解了这个。我想到 ContextMenuStripToolStripDropDownMenu 能够实现其基类 ToolStripDropDown 无法提供的自动滚动行为。最初,我避免使用这些替代控件,因为它们通常会增加很大的余量。这可以通过 ShowImageMarginShowCheckMargin 删除。即使执行此操作后,仍会保留很小的边距(大约 5 像素)。这可以通过覆盖 DefaultPadding 属性来删除:

public class MyDropDown : ToolStripDropDownMenu {

    protected override Padding DefaultPadding {
        get { return Padding.Empty; }
    }

    public MyDropDown() {
        ShowImageMargin = ShowCheckMargin = false;
        RenderMode = ToolStripRenderMode.System;
        MaximumSize = new Size(200, 150);
    }
}

// adding items and calling Show() remains the same as in the question

这会产生一个弹出窗口,其中可以包含任何类型的 ToolStrip 项目,强制 MaximumSize,没有边距,最重要的是,不窃取焦点并且无法接收焦点。

Finally cracked this one. It occurred to me that ContextMenuStrip and ToolStripDropDownMenu are capable of the auto-scrolling behaviour which their base class, ToolStripDropDown, cannot provide. Initially, I avoided these alternative controls because they usually add a wide margin. This can be removed via ShowImageMargin and ShowCheckMargin. Even after doing this, a small (approx 5px) margin remains. This can be removed by overriding the DefaultPadding property:

public class MyDropDown : ToolStripDropDownMenu {

    protected override Padding DefaultPadding {
        get { return Padding.Empty; }
    }

    public MyDropDown() {
        ShowImageMargin = ShowCheckMargin = false;
        RenderMode = ToolStripRenderMode.System;
        MaximumSize = new Size(200, 150);
    }
}

// adding items and calling Show() remains the same as in the question

This results in a popup window which can contain any type of ToolStrip item, enforces MaximumSize, has no margin and, most importantly, does not steal focus and cannot receive focus.

韵柒 2024-10-06 13:20:13

这是你的克星:

internal virtual bool RequiresScrollButtons
{
    get
    {
        return false;
    }
    set
    {
    }
}

它是内部的,你无法超越它。您可以通过修复焦点窃取行为来恢复使用表单的方法。将其粘贴到表单类中:

protected override bool ShowWithoutActivation
{
    get { return true; }
}

This is your nemesis:

internal virtual bool RequiresScrollButtons
{
    get
    {
        return false;
    }
    set
    {
    }
}

It is internal, you cannot override it. You can revive your approach of using a Form by fixing the focus stealing behavior. Paste this into the form class:

protected override bool ShowWithoutActivation
{
    get { return true; }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文