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

时间:2010-10-29 11:07:25

标签: c# winforms toolstripdropdown

我正在使用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的问题,其托管控件仍然可以将焦点从打开它的表单上移开。)

2 个答案:

答案 0 :(得分:2)

最后破解了这个。我突然想到ContextMenuStripToolStripDropDownMenu能够执行其基类ToolStripDropDown无法提供的自动滚动行为。最初,我避免使用这些替代控件,因为它们通常会增加很多。这可以通过ShowImageMarginShowCheckMargin删除。即使在这样做之后,仍然存在小的(大约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,没有边距,最重要的是,不会窃取焦点而无法获得焦点。

答案 1 :(得分:1)

这是你的克星:

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

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

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