我们紧接着上篇,这篇将介绍如何使用Windows.UI.Popups API,创建PopupMenu菜单
和处理oncontextmenu事件.
-----------------------------------我是华丽的分割线-----------------------------------------
我们紧接着上篇,这篇将介绍如何使用Windows.UI.Popups API,创建PopupMenu菜单
和处理oncontextmenu事件.

本篇将介绍如下2个方面:
  a)为一个文件创建一个上下文菜单
  b)在显示文本中替换原来的上下文菜单

我们的创建的步骤如下:
  1)为了组织文件方便,我们先建一个文件夹ContextMenu
  2)向文件夹中添加如下文件:
    ShowAContextMenu.xaml,ReplaceADefaultContextMenu.xaml
  创建方法请参照前一篇.
3)此时的解决方案结构如下:

4)向我们的DataSource添加导航所需要的信息
  修改我们的SampleDataSource.cs文件中的SampleDataSource类中的代码,
  代码如下: 

View Code

        public SampleDataSource(){#region Group1var group1 = new SampleDataGroup("FilePicker","Use Windows.Storage.Pickers API","Access and save files using the file picker","Assets/FilePicker.jpg","");group1.Items.Add(new SampleDataItem("FilePicker-PickASinglePhoto","Pick a single photo","only one file can selected,file type is jpg,jpeg,png","Assets/FilePicker.jpg","only one file can selected ","",group1,typeof(PickASinglePhoto)));group1.Items.Add(new SampleDataItem("FilePicker-PickMultipleFiles","Pick multiple files","you can pick multiple files","Assets/FilePicker.jpg","pick multiple files","",group1,typeof(PickMultipleFiles)));group1.Items.Add(new SampleDataItem("FilePicker-PickAFolder","Pick a folder","you can pick a folder","Assets/FilePicker.jpg","Pick a folder","",group1,typeof(PickAFolder)));group1.Items.Add(new SampleDataItem("FilePicker-SaveAFile","Save a file","you can save a file","Assets/FilePicker.jpg","Save a file","",group1,typeof(SaveAFile)));this.AllGroups.Add(group1);#endregion#region Group2var group2 = new SampleDataGroup("FileAceess","Using Windows.Storage API","File access","Assets/FileAccess.jpg","");group2.Items.Add(new SampleDataItem("FileAceess-CreatingAFile","Create a file","Using CreateFileAsync Create a file","Assets/FileAccess.jpg","Using CreateFileAsync","",group2,typeof(CreatingAFile)));group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingText","Write And Read A Text","Using WriteTextAsync,ReadTextAsync Write And Read  Text","Assets/FileAccess.jpg","Using WriteTextAsync,ReadTextAsync","",group2,typeof(WritingAndReadingText)));group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingBytes","Writing and reading bytes in a file","Using WriteBufferAsync,ReadBufferAsync Write And Read bytes","Assets/FileAccess.jpg","Using WriteBufferAsync,ReadBufferAsync","",group2,typeof(WritingAndReadingBytes)));group2.Items.Add(new SampleDataItem("FileAceess-WritingAndReadingUsingStream","Writing and reading using a stream","Using OpenAsync Writing and reading using a stream","Assets/FileAccess.jpg","Using OpenAsync","",group2,typeof(WritingAndReadingUsingStream)));group2.Items.Add(new SampleDataItem("FileAceess-DisplayingFileProperties","Displaying file properties","Using GetBasicPropertiesAsync  Get File Properties","Assets/FileAccess.jpg","Using GetBasicPropertiesAsync","",group2,typeof(DisplayingFileProperties)));group2.Items.Add(new SampleDataItem("FileAceess-PersistingAccess","Persisting access to a storage item for future use","Using MostRecentlyUsedList","Assets/FileAccess.jpg","Using MostRecentlyUsedList","",group2,typeof(PersistingAccess)));group2.Items.Add(new SampleDataItem("FileAceess-CopyAFile","Copy a file","Using CopyAsync Copy a file","Assets/FileAccess.jpg","Using CopyAsync","",group2,typeof(CopyAFile)));group2.Items.Add(new SampleDataItem("FileAceess-DeleteAFile","Delete a file","Using DeleteAsync Delete a file","Assets/FileAccess.jpg","Using DeleteAsync","",group2,typeof(DeleteAFile)));this.AllGroups.Add(group2);#endregion#region Group3var group3 = new SampleDataGroup("AccountPictureName","Use Windows.System.UserProfile API","Account Picture Name","Assets/AccountPictureName.jpg","");group3.Items.Add(new SampleDataItem("AccountPictureName-GetUserDisplayName","Get User DisplayName","Use UserInformation.GetDisplayNameAsync Get User DisplayName","Assets/AccountPictureName.jpg","Use UserInformation.GetDisplayNameAsync","",group3,typeof(GetUserDisplayName)));group3.Items.Add(new SampleDataItem("AccountPictureName-GetUserFirstLastName","Get First Last Name","Use UserInformation.GetFirstNameAsync,GetLastNameAsync Get First Name","Assets/AccountPictureName.jpg","Use UserInformation.GetFirstNameAsync ","",group3,typeof(GetUserFirstLastName)));group3.Items.Add(new SampleDataItem("AccountPictureName-GetAccountPicture","Get Account Picture","Use UserInformation.GetAccountPicture Get Account Picture","Assets/AccountPictureName.jpg","Use UserInformation.GetAccountPicture","",group3,typeof(GetAccountPicture)));group3.Items.Add(new SampleDataItem("AccountPictureName-SetAccountPictureAndListen","Set AccountPicture And Listen","Use UserInformation.SetAccountPicturesAsync Set AccountPicture","Assets/AccountPictureName.jpg","Use UserInformation.SetAccountPicturesAsync","",group3,typeof(SetAccountPictureAndListen)));this.AllGroups.Add(group3);#endregion#region Group4var group4 = new SampleDataGroup("ApplicationSettings","ApplicationSettings"," Use the Windows.UI.ApplicationSettings namespace and WinJS.UI.SettingsFlyout","Assets/ApplicationSettings.jpg","");group4.Items.Add(new SampleDataItem("ApplicationSettings-Default","Default behavior with no settings integration","Default behavior ","Assets/ApplicationSettings.jpg","Default behavior with no settings integration","",group4,typeof(Default)));group4.Items.Add(new SampleDataItem("ApplicationSettings-AddSettings","Add settings commands to the settings charm","Add settings","Assets/ApplicationSettings.jpg","Add settings commands to the settings charm ","",group4,typeof(AddSettings)));this.AllGroups.Add(group4);#endregion#region Group5var Group5 = new SampleDataGroup("AssociationLaunching","Use Windows.System.Launcher API","Association Launching","Assets/AssociationLaunching.jpg","");Group5.Items.Add(new SampleDataItem("AssociationLaunching-LaunchFile","Launching a file","Use Windows.System.Launcher.LaunchFileAsync","Assets/AssociationLaunching.jpg","Use Windows.System.Launcher.LaunchFileAsync","",Group5,typeof(LaunchFile)));Group5.Items.Add(new SampleDataItem("AssociationLaunching-LaunchUri","Launching a URI","Use Windows.System.Launcher.LaunchUriAsync","Assets/AssociationLaunching.jpg","Use Windows.System.Launcher.LaunchUriAsync","",Group5,typeof(LaunchUri)));Group5.Items.Add(new SampleDataItem("AssociationLaunching-ReceiveFile","Receiving a file","Receiving a file","Assets/AssociationLaunching.jpg","Receiving a file","",Group5,typeof(ReceiveFile)));Group5.Items.Add(new SampleDataItem("AssociationLaunching-ReceiveUri","Receiving a URI","Receiving a URI","Assets/AssociationLaunching.jpg","Receiving a URI","",Group5,typeof(ReceiveUri)));this.AllGroups.Add(Group5);#endregion#region Group6var Group6 = new SampleDataGroup("BackgroundTransfer","Use Windows.Networking.BackgroundTransfer API","BackgroundDownloader And BackgroundUploader","Assets/BackgroundTransfer.jpg","");Group6.Items.Add(new SampleDataItem("BackgroundTransfer-DownloadFile","Download Files","Use BackgroundDownloader","Assets/BackgroundTransfer.jpg","BackgroundDownloader","",Group6,typeof(DownloadFile)));Group6.Items.Add(new SampleDataItem("BackgroundTransfer-UploadFile","Upload Files","Use BackgroundUploader","Assets/BackgroundTransfer.jpg","BackgroundUploader","",Group6,typeof(UploadFile)));this.AllGroups.Add(Group6);#endregion#region Group7var Group7 = new SampleDataGroup("Clipboard","Use Windows.ApplicationModel.DataTransfer API","ClipboardOperation","Assets/Clipboard.jpg","");Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteText","Copy and paste text","Use Clipboard.GetContent,Clipboard.SetContent","Assets/Clipboard.jpg","Clipboard.GetContent,Clipboard.SetContent","",Group7,typeof(CopyAndPasteText)));Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteImage","Copy and paste an image","Use Clipboard.GetContent,Clipboard.SetContent","Assets/Clipboard.jpg","Clipboard.GetContent,Clipboard.SetContent","",Group7,typeof(CopyAndPasteImage)));Group7.Items.Add(new SampleDataItem("Clipboard-CopyAndPasteFile","Copy and paste files","Use Clipboard.GetContent,Clipboard.SetContent","Assets/Clipboard.jpg","Clipboard.GetContent,Clipboard.SetContent","",Group7,typeof(CopyAndPasteFile)));Group7.Items.Add(new SampleDataItem("Clipboard-OtherClipboardOperation","Other Clipboard operations","Use Clipboard.GetContent,Clipboard.SetContent","Assets/Clipboard.jpg","Clipboard.GetContent,Clipboard.SetContent","",Group7,typeof(OtherClipboardOperation)));this.AllGroups.Add(Group7);#endregion#region Group8var Group8 = new SampleDataGroup("Compression","Use Windows.Storage.Compression API","Compression And Decompression","Assets/Compression.jpg","");Group8.Items.Add(new SampleDataItem("Compression-CompressionAndDecompression","Compression And Decompression","Use Windows.Storage.Compression API","Assets/Compression.jpg","Compression And Decompression","",Group8,typeof(CompressionAndDecompression)));this.AllGroups.Add(Group8);#endregion#region Group9var Group9 = new SampleDataGroup("MediaButtons","Use Windows.Media API","Media Buttons","Assets/MediaButtons.jpg","");Group9.Items.Add(new SampleDataItem("MediaButtons-MediaEvents","Media Events","Use Windows.Media API","Assets/MediaButtons.jpg","Listening to hardware media transport events","",Group9,typeof(MediaEvents)));this.AllGroups.Add(Group9);#endregion#region Group10var Group10 = new SampleDataGroup("ContactPicker","Use Windows.ApplicationModel.Contacts API","Contact Picker","Assets/ContactPicker.jpg","");Group10.Items.Add(new SampleDataItem("ContactPicker-SinglePicker","Pick a single contact","Use ContactPicker.PickSingleContactAsync()","Assets/ContactPicker.jpg","PickSingleContactAsync","",Group10,typeof(SinglePicker)));Group10.Items.Add(new SampleDataItem("ContactPicker-MultiplePicker","Pick multiple contacts","Use ContactPicker.PickMultipleContactsAsync()","Assets/ContactPicker.jpg","PickMultipleContactsAsync","",Group10,typeof(MultiplePicker)));this.AllGroups.Add(Group10);#endregion#region Group11var Group11 = new SampleDataGroup("ContextMenu","Use Windows.UI.Popups API","Context Menu","Assets/ContextMenu.jpg","");Group11.Items.Add(new SampleDataItem("ContextMenu-ShowAContextMenu","Show a context menu","Show a context menu","Assets/ContextMenu.jpg","Show a context menu","",Group11,typeof(ShowAContextMenu)));Group11.Items.Add(new SampleDataItem("ContextMenu-ReplaceADefaultContextMenu","Replace a default context menu","Replace a default context menu","Assets/ContextMenu.jpg","Replace a default context menu","",Group11,typeof(ReplaceADefaultContextMenu)));this.AllGroups.Add(Group11);#endregion}

5)我们的导航这样就做好了,效果图:

  点击 ContextMenu

6)为一个文件创建一个上下文菜单
  我们使用控件的RightTapped事件,来处理右击,然后在右击的位置创建一个PopupMenu,
  使用PopupMenu的ShowForSelectionAsync方法显示上下文菜单。
  修改ShowAContextMenu.xaml的xaml

View Code

   <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions><Grid x:Name="Input" Grid.Row="0"><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions><TextBlock Grid.Row="0" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap">Right-click the image to show a simple context menu. Using touch, the press-and-hold gesture will also trigger the context menu.</TextBlock><Image x:Name="AttachmentImage" Grid.Row="1" HorizontalAlignment="Left" Stretch="None" Source="../Assets/logo.jpg" /></Grid><Grid x:Name="Output" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top"><TextBlock x:Name="OutputTextBlock" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap"/></Grid></Grid>

  修改后台代码:

View Code

    public sealed partial class ShowAContextMenu : Page{public ShowAContextMenu(){this.InitializeComponent();//注册右击事件AttachmentImage.RightTapped += new RightTappedEventHandler(AttachmentImage_RightTapped);}/// <summary>/// Invoked when this page is about to be displayed in a Frame./// </summary>/// <param name="e">Event data that describes how this page was reached.  The Parameter/// property is typically used to configure the page.</param>protected override void OnNavigatedTo(NavigationEventArgs e){}private async void AttachmentImage_RightTapped(object sender, RightTappedRoutedEventArgs e){// Create a menu and add commands specifying a callback delegate for each.// Since command delegates are unique, no need to specify command Ids.var menu = new PopupMenu();menu.Commands.Add(new UICommand("Open with", (command) =>{OutputTextBlock.Text = "'" + command.Label + "' selected";}));menu.Commands.Add(new UICommand("Save attachment", (command) =>{OutputTextBlock.Text = "'" + command.Label + "' selected";}));// We don't want to obscure content, so pass in a rectangle representing the sender of the context menu event.// We registered command callbacks; no need to handle the menu completion eventOutputTextBlock.Text = "Context menu shown";//显示上下文菜单var chosenCommand = await menu.ShowForSelectionAsync(GetElementRect((FrameworkElement)sender));if (chosenCommand == null) // The command is null if no command was invoked.
            {OutputTextBlock.Text = "Context menu dismissed";}}public static Rect GetElementRect(FrameworkElement element){GeneralTransform buttonTransform = element.TransformToVisual(null);Point point = buttonTransform.TransformPoint(new Point());return new Rect(point, new Size(element.ActualWidth, element.ActualHeight));}}

  效果图

  点击 Open with

7)在显示文本中替换原来的上下文菜单
  我们使用控件的ContextMenuOpening事件,通过设置 e.Handled = true;来处理掉系统默认的
  上下文菜单,然后在右击的位置创建一个PopupMenu,
  使用PopupMenu的ShowForSelectionAsync方法显示上下文菜单。
  修改ReplaceADefaultContextMenu.xaml的xaml

View Code

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="*"/></Grid.RowDefinitions><Grid x:Name="Input" Grid.Row="0"><Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><TextBlock Grid.Row="0" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap">Select and right-click or tap on the selection in the below text box to show a custom context menu for text.</TextBlock><TextBox x:Name="ReadOnlyTextBox" Grid.Row="1" IsReadOnly="True" TextWrapping="Wrap" Text="http://www.cnblogs.com/refactor"/></Grid><Grid x:Name="Output" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top"><TextBlock x:Name="OutputTextBlock" Style="{StaticResource SubheaderTextStyle}" TextWrapping="Wrap"/></Grid></Grid>

  修改后台代码:

View Code

    public sealed partial class ReplaceADefaultContextMenu : Page{public ReplaceADefaultContextMenu(){this.InitializeComponent();//在系统处理显示上下文菜单交互时发生的时间ReadOnlyTextBox.ContextMenuOpening += new ContextMenuOpeningEventHandler(ReadOnlyTextBox_ContextMenuOpening);}/// <summary>/// Invoked when this page is about to be displayed in a Frame./// </summary>/// <param name="e">Event data that describes how this page was reached.  The Parameter/// property is typically used to configure the page.</param>protected override void OnNavigatedTo(NavigationEventArgs e){}// returns a rect for selected text// if selection is multiline then rect is unreliable// if no text is selected, returns caret location// textbox should not be emptyprivate Rect GetTextboxSelectionRect(TextBox textbox){Rect rectFirst, rectLast;if (textbox.SelectionStart == textbox.Text.Length){rectFirst = textbox.GetRectFromCharacterIndex(textbox.SelectionStart - 1, true);}else{rectFirst = textbox.GetRectFromCharacterIndex(textbox.SelectionStart, false);}int lastIndex = textbox.SelectionStart + textbox.SelectionLength;if (lastIndex == textbox.Text.Length){rectLast = textbox.GetRectFromCharacterIndex(lastIndex - 1, true);}else{rectLast = textbox.GetRectFromCharacterIndex(lastIndex, false);}GeneralTransform buttonTransform = textbox.TransformToVisual(null);Point point = buttonTransform.TransformPoint(new Point());return new Rect(point.X + rectFirst.Left,point.Y + rectFirst.Top,rectLast.Right - rectFirst.Left,rectLast.Bottom - rectFirst.Top);}private async void ReadOnlyTextBox_ContextMenuOpening(object sender, ContextMenuEventArgs e){//将系统上下文菜单标记成已处理e.Handled = true;TextBox textbox = (TextBox)sender;if (textbox.SelectionLength > 0){// Create a menu and add commands specifying an id value for each instead of a delegate.var menu = new PopupMenu();menu.Commands.Add(new UICommand("Copy", null, 1));menu.Commands.Add(new UICommandSeparator());menu.Commands.Add(new UICommand("Highlight", null, 2));menu.Commands.Add(new UICommand("Look up", null, 3));OutputTextBlock.Text = "Context menu shown";Rect rect = GetTextboxSelectionRect(textbox);//显示上下文菜单var chosenCommand = await menu.ShowForSelectionAsync(rect);if (chosenCommand != null){switch ((int)chosenCommand.Id){case 1:String selectedText = ((TextBox)sender).SelectedText;var dataPackage = new DataPackage();dataPackage.SetText(selectedText);//Copy
                            Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage);OutputTextBlock.Text = "'" + chosenCommand.Label + "'(" + chosenCommand.Id.ToString() + ") selected; '" + selectedText + "' copied to clipboard";break;case 2:OutputTextBlock.Text = "'" + chosenCommand.Label + "'(" + chosenCommand.Id.ToString() + ") selected";break;case 3:OutputTextBlock.Text = "'" + chosenCommand.Label + "'(" + chosenCommand.Id.ToString() + ") selected";break;}}else{OutputTextBlock.Text = "Context menu dismissed";}}else{OutputTextBlock.Text = "Context menu not shown because there is no text selected";}}}

  效果图

  点击Copy

未完待续,敬请期待...
转载请注明出处:http://www.cnblogs.com/refactor/

转载于:https://www.cnblogs.com/refactor/archive/2012/06/26/2551894.html

图解使用Win8Api进行Metro风格的程序开发十二----上下文菜单相关推荐

  1. 图解使用Win8Api进行Metro风格的程序开发十一----联系人选择

    我们紧接着上篇,这篇将介绍如何使用Windows.ApplicationModel.Contacts API 中的ContactPicker来选择联系人,使用ContactPicker的PickSin ...

  2. 图解使用Win8Api进行Metro风格的程序开发二----使用文件选择器访问和保存文件

    我们紧接着上篇,这篇将介绍如何使用文件选择器访问和保存文件 -----------------------------------我是华丽的分割线--------------------------- ...

  3. 微信小程序开发(十二)富文本插件wxParse的使用

    昨天一位网友问我小程序怎么解析富文本.他尝试过把html转出小程序的组件,但是还是不成功,我说可以把内容剥离出来.但是这两种方法都是不行了.后来找到了wxParse-微信小程序富文本解析组件. 特性 ...

  4. 微信小程序开发笔记二(WXSS和CSS样式美化)

    微信小程序开发笔记二(WXSS和CSS样式美化) 一.CSS基本知识 1.Class选择器的定义 2.ID选择器的定义 3.ID选择器和class选择器的区别 4.CSS中设置颜色 5.CSS中的文本 ...

  5. 微信小程序开发(十)小程序支付-查询退款

    应用场景 提交退款申请后,通过调用该接口查询退款状态.退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态. 接口说明 这里退款还是根据商户订单号-out_tr ...

  6. WP7上Metro风格的程序栏图标汇总

    在开发一款WP7程序时,应用程序图标是我们不可或缺的资源.轩辕在这里对网上的大部分Metro风格的应用程序栏图标进行了总结,希望可以给园子里面的各位有点帮助. 1. 其实Microsoft Visua ...

  7. 微信小程序开发系列二:微信小程序的视图设计

    大家如果跟着我第一篇文章 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 一起动手,那么微信小程序的开发环境一定搭好了.效果就是能把该小程序的体验版以二维码的方式发送给其他朋友使用. 这个系列 ...

  8. Python+微信小程序开发(二)代码构成和宿主环境

    一.小程序代码构成 ​在上一篇文章中,我们通过开发者工具载入模板快速创建了一个QuickStart项目.这个项目里边生成了不同类型的文件: .json 后缀的 JSON 配置文件 .wxml 后缀的  ...

  9. 现学现卖微信小程序开发(二)

    现学现卖微信小程序开发(一) 现学现卖微信小程序开发(三):引入Rx,为小程序插上翅膀 一个Todo应用的小程序版 好的,那么下一步我们就先照猫画虎,新建一个todos文件夹,然后一套四样同名文件准备 ...

最新文章

  1. Linux下数值计算
  2. reg类型变量综合电路_verilog中reg和wire类型的区别
  3. 原创 | 比新基建还火,数字孪生究竟有哪些应用价值?
  4. AI女神李飞飞:成为顶尖科学家的人生路
  5. 基带信号传输之信道均衡
  6. VMware VDI技术与实现
  7. STM32F0使用LL库实现MS5536C通讯
  8. Spring中的观察者模式
  9. 矩池云上安装CUDA头文件教程
  10. 重拾JAVA之WinForm实战之(二)
  11. 广发银行网上银行安全控件官方版
  12. python转化时区
  13. 【UI】关于如何画设计稿(基础篇)
  14. 完美解决VS2003.Net fatal error LNK1201: 写入程序数据库“.pdb”时出错
  15. [C/C++]宽字符与控制台输出
  16. Rate Limiting速率限制
  17. 通过Java访问数据库---JDBC
  18. xinxin- 新鑫牌计算器
  19. 阿里Java岗P5-P7成长笔记【3283页PDF文档免费领】
  20. Android权限说明

热门文章

  1. 少有人挖但仍可获得奖金的10类Web 漏洞(下)
  2. python 闭包和装饰器
  3. CentOS+nginx+uwsgi+Python 多站点环境搭建
  4. 海运业务常用缩略语 一
  5. 优美的函数式语言Haskell
  6. Sqlite查询优化技巧——将LIKE语句转换为比较语句 -转
  7. L1-066 猫是液体 (5 分)-PAT 团体程序设计天梯赛 GPLT
  8. LeetCode 357. Count Numbers with Unique Digits
  9. 1120. Friend Numbers (20)-PAT甲级真题
  10. 【note】Java程序设计基础第五版(下)