3

我正在使用一个ToolStripDropDown控件来实现自定义 ComboBox 类控件的下拉部分。为了在视觉上吸引人,我MaximumSize在下拉列表中强加 a 并手动指定其中每个的宽度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()on ListViewItem)。

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

(顺便说一句,我已经尝试过很多次使用Form下拉部分来制作类似的控件 - 尽管尝试了许多解决方案来防止弹出窗口在单击其控件时窃取焦点或获得焦点,但这似乎是一个死胡同。我有也排除了使用ToolStripControlHost,其托管控件仍然可以将焦点从打开它的表单上移开。)

4

2 回答 2

3

终于破解了这个。我突然想到ContextMenuStrip,并且ToolStripDropDownMenu能够实现其基类ToolStripDropDown无法提供的自动滚动行为。最初,我避免使用这些替代控件,因为它们通常会增加很大的余量。这可以通过ShowImageMargin和删除ShowCheckMargin。即使在这样做之后,仍然有一个小的(大约 5px)边距。这可以通过覆盖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,没有边距,最重要的是,不会窃取焦点并且无法接收焦点。

于 2010-10-29T17:55:44.043 回答
1

这是你的克星:

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

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

protected override bool ShowWithoutActivation
{
    get { return true; }
}
于 2010-10-29T14:41:11.703 回答