0

Windows Phone には、コントロールのポップアップ メニューを作成できるContextMenuという機能があります。

ただし、メニュー項目のリストが非常に大きい場合、画面に収まらないものもあります。次の簡単な例は、ポイントを示しています。

xamlで:

Toolkit を使用するので、追加します。

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 では何もしていません

private void nullAction(object sender, RoutedEventArgs e)
        {

        }

DesignHeight 値は、既定の WP7 ページの標準です。DesignHeight="768"

ご覧のとおり、「ボタン 1」コントロールを長押しすると、メニューが表示されますが、完全ではありません。一部のアイテムは表示されません。私の場合、このメニューをスクロール可能にすることが最善の決定でした。これは、 ScrollViewerを使用して実行できます。

そこで、Scrollviewer と 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>

成功?いいえ、このリストはスクロールできますが、項目を選択することはできません。

私の質問は、それを修正する方法ですか?

マルチタッチを使用しますか?(私はそれについてあまり知りません)

おそらく、Scrollviewer にプロパティを追加する必要がありますか?

他のアイデアはありますか?

[更新]また、スクロールビューアーが追加された場合、アイテムのタップ/クリック ハンドラーの動作が変わることがわかりました。通常、アイテムをタップすると、コンテキスト メニューが閉じられ、ハンドラ メソッドが実行されます。scrollviewer では、コンテキスト メニューが閉じず、手動で閉じるにはもう 1 回タップする必要があります。なぜそれが起こっているのですか?

4

1 に答える 1

0

ネイティブの ContextMenu がこれを許可しない場合、問題を解決する最善の方法は、独自の実装を作成することです。

新しいコンテキスト メニューは、いくつかの項目を選択できるポップアップに表示され、その項目はスクロール可能である必要があります。そう:

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 のように見える UserControl ですつまり、Grid/StackPanel 上の単純な TextBox です。

ネイティブの ContextMenu が xaml ファイルに次のように追加されます。

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

代わりに、Hold イベントを介して ScrollableContextMenu オブジェクトを呼び出す必要があります。

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();
        }

定義されたリストは、コンテキスト メニューのヘッダーのリストです (どこかで生成する必要があります)。

listBoxTap イベント時:

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;
            }

それが唯一の解決策で、本当に助かりました。それが他の誰かを助けることを願っています。

于 2013-02-20T06:01:54.050 に答える