滚动文本菜单项 [英] Scrolling ContextMenu items

查看:95
本文介绍了滚动文本菜单项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Windows手机有一个叫文本菜单,它允许创建控件的弹出式菜单。

In Windows Phone there is a feature called ContextMenu, which allows to create a popup menu for controls.

但是,如果列表功能菜单项是相当大的,他们中的一些不适合在屏幕上。下面的简单示例显示了这一点:

However, if the list of menu items is quite big, some of them doesn't fit the screen. The following simple example will show the point:

在XAML:

我们将使用工具包,因此增加

We will be using Toolkit, so adding

xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"

再例如:

   <Button Content="Button 1" Height="72" HorizontalAlignment="Left" Margin="160,400,0,0" Name="button1" VerticalAlignment="Top" Width="160">
        <toolkit:ContextMenuService.ContextMenu>
            <toolkit:ContextMenu>                    
                    <toolkit:MenuItem Header="Action A" Name="miActionA1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />
                    <toolkit:MenuItem Header="Action B" Name="miActionB1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />
                    <toolkit:MenuItem Header="Action C" Name="miActionC1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />
                    <toolkit:MenuItem Header="Action D" Name="miActionD1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />
                    <toolkit:MenuItem Header="Action E" Name="miActionE1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />
                    <toolkit:MenuItem Header="Action F" Name="miActionF1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />                      
            </toolkit:ContextMenu>
        </toolkit:ContextMenuService.ContextMenu>
    </Button>

目前nullAction我们什么都不做。

At nullAction we're doing nothing

private void nullAction(object sender, RoutedEventArgs e)
        {

        }



DesignHeight值是默认的WP7页面是 DesignHeight =768

正如你所看到的,当你长按了按钮1的控制,菜单显示,但不完全。某些项
是不可见的。就我而言,最好的决定是让该菜单滚动。可以做,使用的ScrollViewer

As you can see, when you long tap the "Button 1" control, the menu is shown, but not completely. Some items are not visible. In my case, the best decision was to make this menu scrollable. That can be done, using ScrollViewer.

所以,我们覆盖的ScrollViewer和StackPanel中的菜单项。

So, we cover the menu items with Scrollviewer and StackPanel.

 <Button Content="Button 1" Height="72" HorizontalAlignment="Left" Margin="160,400,0,0" Name="button1" VerticalAlignment="Top" Width="160">
        <toolkit:ContextMenuService.ContextMenu>
            <toolkit:ContextMenu>
                <ScrollViewer>
                    <StackPanel>
                    <toolkit:MenuItem Header="Action A" Name="miActionA1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />
                    <toolkit:MenuItem Header="Action B" Name="miActionB1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />
                    <toolkit:MenuItem Header="Action C" Name="miActionC1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />
                    <toolkit:MenuItem Header="Action D" Name="miActionD1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />
                    <toolkit:MenuItem Header="Action E" Name="miActionE1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />
                    <toolkit:MenuItem Header="Action F" Name="miActionF1" BorderBrush="Black" BorderThickness="1" Click="nullAction" />
                    </StackPanel>
                </ScrollViewer>
            </toolkit:ContextMenu>
        </toolkit:ContextMenuService.ContextMenu>
    </Button>

成功?不,因为你可以滚动这个列表中,但
不能选择项目了。

Success? Nope, because you can scroll this list, but can't choose the item down.

我的问题,是如何解决的呢?

使用多点触控? (我不很了解吧)

Use multitouch? (I don't know much about it)

也许,我需要将一些属性添加到Scrolviewer?

Perhaps, I need to add some property to Scrolviewer?

任何其他的想法?

[更新] 同时,发现水龙头/点击物品的处理程序改变行为,如果添加的ScrollViewer。通常情况下,当你点击的项目,在上下文菜单中关闭和处理方法执行。随着ScrollViewer中,上下文菜单没有关闭,需要多一个水龙头手动关闭它。为什么这么回事?

[updated] Also, found that tap/click handlers for items change behavior, if scrollviewer is added. Normally, when you tap the item, the context menu closes and the handler method executes. With scrollviewer, the context menu doesn't close, needs one more tap to close it manually. Why's that happening?

推荐答案

如果本地的ContextMenu不允许这一点,那么,解决问题的最好办法,就是写你自己的实现。

If the native ContextMenu doesn't allow this, then, the best way to solve a problem, is to write your own implementation.

新的上下文菜单应符合几项选择弹出所示,这项目必须滚动。所以:

The new context menu should be shown in a popup with a choice of several items, and that items must be scrollable. So:

public class ScrollableContextMenu
    {
        private Popup p;
        public delegate void TapHandler(object sender, System.Windows.Input.GestureEventArgs e);
        public event TapHandler ListBoxTap;

        private ListBox listBox;

        public ListBox ListBox
        {
            get { return listBox; }
            set { listBox = value; }
        }

        /// <summary>
        /// Create new Context Menu. The items of Context Menu will be taken from given list
        /// </summary>
        /// <param name="page"></param>
        /// <param name="items"></param>
        public ScrollableContextMenu(PhoneApplicationPage page, List<string> items)
        {
            p = new Popup();

           // Generate popup properties, i.e. height, width, e.t.c.

            Canvas canvas = new Canvas();

            // Generate canvas main properties

            p.Child = canvas;

            Border border = new Border();

            // Now create border and its main properties

            canvas.Children.Add(border);

            // StackPanel.
            StackPanel panel = new StackPanel();
            panel.Orientation = System.Windows.Controls.Orientation.Vertical;

            // Create listBox, that we will be scrolling
            listBox = new ListBox();
            // Create listbox main properties

            // Fill the listbox with items. 
            foreach (string item in items)
                listBox.Items.Add(new ScrollableContextMenuItem(item));
            listBox.Tap += listBoxTap;
            panel.Children.Add(listBox);
            border.Child = panel;
        }

        public void Show()
        {
            // Open the popup.
            p.IsOpen = true;
            p.UpdateLayout();
        }

        public void Close()
        {
            // Close it
            p.IsOpen = false;
            p.UpdateLayout();
        }

        private void listBoxTap(object sender,  System.Windows.Input.GestureEventArgs e)
        {
            // Invoke hanlder if it exists
            if (ListBoxTap != null)
                ListBoxTap(sender, e);
        }



ScrollableContextMenuItem 的是一个用户控件,它看起来应该像原生的ContextMenuItem。总之,一切都结束了网格/ StackPanel的一个简单的文本框。

The ScrollableContextMenuItem is a UserControl, which should look like native ContextMenuItem. In short, it's a simple TextBox over Grid/StackPanel.

本机的文本菜单添加到XAML文件

The native ContextMenu is added to the xaml file as

<toolkit:ContextMenuService.ContextMenu>
        <toolkit:ContextMenu>
               <toolkit:MenuItem Header="..." ... Click="miClickEvent"/>
                <!-- ... --!>
        </toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>



相反,ScrollableContextMenu对象应该通过保持事件称为:

Instead, the ScrollableContextMenu object should be called via Hold event:

button.Hold += new EventHandler<System.Windows.Input.GestureEventArgs>(SomeHoldEvent);



 private void SomeHoldEvent(object sender, EventArgs e)
        {
            contextMenu = new ScrollableContextMenu(this, definedList);
            contextMenu.ListBoxTap +=new ScrollableContextMenu.TapHandler(contextMenu_ListBoxTap);
            contextMenu.Show();
        }



当定义列表头上下文菜单的列表(应该生成。某处)

Where the defined list is a List of headers for context menu (should be generated somewhere).

目前listBoxTap事件:

At listBoxTap event:

private void contextMenu_ListBoxTap(object sender, EventArgs e)
        {
            int index = contextMenu.ListBox.SelectedIndex;
            switch (index)
            {
                // items index starts with zero
                case 0:
                    // Call the click event for this one, it should be implemented already, when we've written it for native context menu
                    MiClickEvent(this, EventArgs.Empty);
                    contextMenu.Close();
                    break;
                // implement other handlers here
                default:
                    contextMenu.Close();
                    break;
            }

这是唯一的解决方案,真正帮助了我。希望它会帮助别人。

That's the only solution, that really helped me. Hope it'll help someone else.

这篇关于滚动文本菜单项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆