【问题标题】:DropDown Menu with ScrollBar in .NET.NET 中带有滚动条的下拉菜单
【发布时间】:2010-07-03 13:31:35
【问题描述】:


我正在尝试制作一个类似于 Windows 资源管理器中使用的 Windows Vista/7 面包屑栏的用户控件。

但是,当我显示包含许多子项目的面包屑的下拉菜单时,我会得到一个很长的列表,有时会超出屏幕大小。
但在 Windows Vista/7 示例中,一次最多显示 18 个项目,当子项目的数量超过此数量 (18) 时,右侧会出现滚动条。

我想知道是否有人知道复制微软的方法。
[即,如何在具有自动滚动功能的控件中放置下拉菜单。]



谢谢。
亚历克斯

【问题讨论】:

  • 下拉菜单到底是什么意思?哪个.net控件? (工具栏上的 DropDownButton ??)
  • 我的意思是 ToolStripDropDown。运行 ContextMenu.Show 或单击 ToolStripMenuItem 时获得的类型。

标签: c# .net vb.net winforms


【解决方案1】:

Windows 7/Vista 面包屑看起来类似于列表视图。 下图给出了我的意思的示例(在 windows xp 上)(单击按钮会出现列表):

这是获取它的代码:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var button = sender as Button;

        // create fake items list
        List<string> strings = new List<string>();
        for (int i = 0; i < 36; i++)
            strings.Add("ITEM " + (i+1));
        var listViewItems = strings.Select(x => new ListViewItem(x, 0)).ToArray();

        // create a new list view
        ListView listView = new ListView();
        listView.View = View.SmallIcon;
        listView.SmallImageList = imageList1;
        listView.MultiSelect = false;

        // add items to listview
        listView.Items.AddRange(listViewItems);

        // calculate size of list from the listViewItems' height
        int itemToShow = 18;
        var lastItemToShow = listViewItems.Take(itemToShow).Last();
        int height = lastItemToShow.Bounds.Bottom + listView.Margin.Top;
        listView.Height = height;

        // create a new popup and add the list view to it
        var popup = new ToolStripDropDown();
        popup.AutoSize = false;
        popup.Margin = Padding.Empty;
        popup.Padding = Padding.Empty;
        ToolStripControlHost host = new ToolStripControlHost(listView);
        host.Margin = Padding.Empty;
        host.Padding = Padding.Empty;
        host.AutoSize = false;
        host.Size = listView.Size;
        popup.Size = listView.Size;
        popup.Items.Add(host);

        // show the popup
        popup.Show(this, button.Left, button.Bottom);
    }
}

编辑:

要获得选中的项目,一种方法如下:

// change some properties (for selection) and subscribe the ItemActivate 
// event of the listView
listView.HotTracking = true;
listView.Activation = ItemActivation.OneClick;
listView.ItemActivate += new EventHandler(listView_ItemActivate);


// the click on the item invokes this method
void listView_ItemActivate(object sender, EventArgs e)
{
    var listview = sender as ListView;
    var item = listview.SelectedItems[0].ToString();
    var dropdown = listview.Parent as ToolStripDropDown;
    // unsubscribe the event (to avoid memory leaks)
    listview.SelectedIndexChanged -= listView_ItemActivate;
    // close the dropdown (if you want)
    dropdown.Close();

    // do whatever you want with the item
    MessageBox.Show("Selected item is: " + item);
}

【讨论】:

  • 谢谢!我从来不知道您可以如此轻松地将 Control [或其派生] 嵌入 ToolStripDropDown 中。你真的很有帮助。
  • 为什么选择 ListView 而不是 ComboBox?
  • @Cody:因为 OP 需要使用右键单击来显示 ListBox。使用组合会略有不同......
  • 这不是我阅读问题的方式。他们想在资源管理器中实现类似于 Windows 7 面包屑导航栏的东西。它使用自定义绘制的 ComboBox,而不是 ListBox。哪里有关于右键单击或 ListBoxes 的说明?
  • @Cody:哦,抱歉,我没有重读第一篇文章,因为我以为我记得但我错了:P ...是的,你是对的,他想模仿面包屑。无论如何,这只是组合自定义的替代方案......也许使用组合框更好,我不知道,OP必须选择:)
【解决方案2】:

我建议用 Spy++ 看看它。一切都由标准的 Windows 控件组成,高度嵌套。下拉菜单被实现为,drumroll,一个组合框。这是一个很大程度上被遗忘的定制,名为ComboBoxEx。我从未见过它的 .NET 包装器,可能是因为它所做的工作很容易被 Windows 窗体中的普通旧 ComboBox 包装器实现。

只需将其 DrawMode 属性设置为 OwnerDrawFixed 并实现 DrawItem 事件以显示图标和文本。 MSDN Library article 中有一个很好的例子。

【讨论】:

    【解决方案3】:

    如果您想访问 Vista API 来呈现栏,请查看Vista Bridge library。您可以在其中一个示例中找到面包屑栏控件的示例。

    不过,我不确定它是否会在 WinXP 上呈现。

    【讨论】:

    •  您的回答为我提供了 Microsoft 构建的面包屑导航,对此我表示感谢。但是,该解决方案没有考虑到滚动条问题,因此我必须将您的建议与 digEmAll 的感谢结合起来。 
    猜你喜欢
    • 2016-11-11
    • 1970-01-01
    • 2010-10-09
    • 2016-12-16
    • 2015-09-26
    • 1970-01-01
    • 2014-03-22
    • 2013-04-06
    • 1970-01-01
    相关资源
    最近更新 更多