C# 滚动上下文菜单项
在Windows Phone中有一个名为ContextMenu的功能,允许为控件创建弹出菜单 但是,如果菜单项列表很大,则其中一些项不适合屏幕。以下简单示例将说明这一点: 在xaml中: 我们将使用Toolkit,因此添加C# 滚动上下文菜单项,c#,windows-phone-7,contextmenu,C#,Windows Phone 7,Contextmenu,在Windows Phone中有一个名为ContextMenu的功能,允许为控件创建弹出菜单 但是,如果菜单项列表很大,则其中一些项不适合屏幕。以下简单示例将说明这一点: 在xaml中: 我们将使用Toolkit,因此添加 xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" 然后举例来说: <Button Content=
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>
DesignHeight值是默认WP7页面的标准值,它是DesignHeight=“768”
如您所见,当您长按“Button 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>
成功?不,因为您可以滚动此列表,但是
无法向下选择项目
我的问题是,如何修复它?
使用多点触摸?(我对此不太了解)
也许,我需要给Scrolviewer添加一些属性
还有其他想法吗
[更新]此外,还发现,如果添加了scrollviewer,则项目的点击/单击处理程序会更改行为。通常,当您点击该项时,上下文菜单关闭,处理程序方法执行。使用scrollviewer时,上下文菜单不会关闭,只需再点击一次即可手动关闭。为什么会发生这种情况?如果本机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);
}
这是唯一的解决办法,它真的帮助了我。希望它能帮助别人
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);
}
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="..." ... Click="miClickEvent"/>
<!-- ... --!>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
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();
}
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;
}