2010-10-29 76 views
1

我正在使用ToolStripDropDown控件来实现自定义ComboBox类控件的下拉部分。为了在视觉上有吸引力,我在下拉列表上施加MaximumSize并手动指定其中的每个ToolStripButton的宽度 - 结果是与弹出的宽度相同的弹出窗口,并且激活它的控件的宽度为下拉部分的高度。如何在固定大小的ToolStripDropDown中滚动

例(简体):

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关于滚动偏移量或将特定项目滚动到视图中的机制(例如ListViewItem上的EnsureVisible())中似乎没有任何方法或属性。

那么,我怎样才能让下拉滚动?任何方法都足够了,无论是滚动条,滚动按钮还是鼠标滚轮。 (顺便说一句,我已经尝试了很多次使用Form来做下拉部分的类似控件 - 尽管尝试了几十种解决方案来防止弹出窗口在点击控件时被盗取焦点或获得焦点,但这似乎是。死胡同我也排除了使用ToolStripControlHost,其托管的控制仍然可以从打开它的形式集中远)

回答

1

最后破解了这一个。我想到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

这是你的克星:

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

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

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

'ShowWithoutActivation'不会阻止窗体的子控件将窗体带入焦点;例如,单击窗体上的一个“TreeView”将使焦点到弹出窗体。 “ShowWithoutActivation”所做的就是在表单最初显示时停止表单的窃取焦点;它可以在此后的任何时间获得焦点。在Vista和7中,这非常明显,因为父窗口周围的投影会发生变化。 – 2010-10-29 17:21:03

+0

我不明白,当用户点击一个按钮时,它不应该得到重点?开始一个关于它的新问题,这个答案。 – 2010-10-29 17:27:32

+0

来自MSDN:“如果您想要显示顶层窗口,但不想通过将输入焦点从当前窗口中取消来中断用户的工作,请使用[ShowWithoutActivation] ...如果您的未激活窗口需要要使用UI控件,您应该考虑使用ToolStrip控件,例如ToolStripDropDown。“ - 正如我所说的,ShowWithoutActivation仅影响对窗体的Show()方法的第一次调用。之后,它表现得像一个普通的形式。没有人再问这个话题,有人问了好几次,从来没有回答过满意的问题。 – 2010-10-29 18:02:01