zoukankan      html  css  js  c++  java
  • 【Win 10应用开发】在RichEditBox中使用自定义菜单

    前面给大伙儿简单介绍了RichEditBox控件的基本用法,以及解决其中的一些小问题。

    本文咱们来看看如何自定义RichEditBox控件的上下文菜单。

    原理比较简单,所以先说一说原理。当RichEditBox控件的上下文菜单即将弹出时,会引发ContextMenuOpening事件,我们需要处理该事件,并且将e.Handled属性设置为true,这样才能阻止默认上下文菜单的弹出

    首先,在RichEditBox控件上声明附加的菜单项,样板XAML如下:

            <RichEditBox Name="redit" ContextMenuOpening="OnContextMenuOpening">
                <FlyoutBase.AttachedFlyout>
                    <MenuFlyout>
                        <MenuFlyoutItem Text="复制" Click="OnCopy"/>
                        <MenuFlyoutItem Text="剪切" Click="OnCut"/>
                        <MenuFlyoutItem Text="粘贴" Click="OnPaste"/>
                        <MenuFlyoutSeparator/>
                        <MenuFlyoutSubItem Text="字号">
                            <MenuFlyoutItem Text="16" Tag="16" Click="OnFontSize" />
                            <MenuFlyoutItem Text="20" Tag="20" Click="OnFontSize"/>
                            <MenuFlyoutItem Text="24" Tag="24" Click="OnFontSize" />
                            <MenuFlyoutItem Text="36" Tag="36" Click="OnFontSize"/>
                            <MenuFlyoutItem Text="48" Tag="48" Click="OnFontSize"/>
                        </MenuFlyoutSubItem>
                        <MenuFlyoutSeparator/>
                        <ToggleMenuFlyoutItem Text="加粗" Click="OnBold" />
                        <MenuFlyoutSeparator/>
                        <MenuFlyoutSubItem Text="下划线">
                            <MenuFlyoutItem Text="无" Tag="-1" Click="OnUnderline" />
                            <MenuFlyoutItem Text="单实线" Tag="0" Click="OnUnderline"/>
                            <MenuFlyoutItem Text="双实线" Tag="1" Click="OnUnderline"/>
                            <MenuFlyoutItem Text="虚线" Tag="2" Click="OnUnderline"/>
                        </MenuFlyoutSubItem>
                    </MenuFlyout>
                </FlyoutBase.AttachedFlyout>
            </RichEditBox>

     通过FlyoutBase类的AttachedFlyout附加属性,可以将派出自FlyoutBase的弹出对象附加到任意的可视化对象上,由于这里咱们用的菜单,所以附加到RichEditBox控件的弹出对象为MenuFlyout实例。

    处理ContextMenuOpening事件,阻止弹出默认的上下文菜单,然后,调用ShowAt方法在指定的坐标处打开菜单。

                e.Handled = true;
                MenuFlyout menu = FlyoutBase.GetAttachedFlyout(redit) as MenuFlyout;
                menu?.ShowAt(redit, new Point(e.CursorLeft, e.CursorTop));

    前面在XAML文档中已通过FlyoutBase的AttachedFlyout附加属性设置了MenuFlyout对象,故此处通过 GetAttachedFlyout方法,可以获取到MenuFlyout实例的引用。

    然后调用ShowAt方法来显示菜单,之所以会调用这个方法,是因为它可以自行指定菜单弹出的位置坐标值。ContextMenuOpening事件的参数e的CursorLeft和CursorTop属性可以得到当前指针的横坐标和纵坐标,再把坐标传给ShowAt方法即可以确定菜单弹出的位置。

    下面代码处理文档的复制、剪切和粘贴功能。

            private void OnCopy(object sender, RoutedEventArgs e)
            {
                redit.Document.Selection.Copy();
            }
    
            private void OnCut(object sender, RoutedEventArgs e)
            {
                redit.Document.Selection.Cut();
            }
    
            private void OnPaste(object sender, RoutedEventArgs e)
            {
                // Paste方法带有一个整型参数,表示要粘贴的格式
                redit.Document.Selection.Paste(0);
            }

    被编辑文档的Selection属性表示文档中正处于选择状态下的文本区域,通常上下文菜单只控制被选的文本,如果当前文档没有选定文本,那么选区就是插入光标所在的位置。

    注意,在粘贴文本时,Paste方法需要一个整数值参数,指定粘贴的格式,0表示自动采用最优格式的文本,常常是RTF文本。有关格式的数值定义请自己参考https://msdn.microsoft.com/en-us/library/windows/desktop/ff729168(v=vs.85).aspx,MSDN是万能的。

    最后是设置字号、加粗、下划线功能的实现。

            private void OnFontSize(object sender, RoutedEventArgs e)
            {
                MenuFlyoutItem item = sender as MenuFlyoutItem;
                // 获取字号
                float size = Convert.ToSingle(item.Tag);
    
                redit.Document.Selection.CharacterFormat.Size = size;
            }
    
            private void OnBold(object sender, RoutedEventArgs e)
            {
                ToggleMenuFlyoutItem item = sender as ToggleMenuFlyoutItem;
                redit.Document.Selection.CharacterFormat.Bold = item.IsChecked ? FormatEffect.On : FormatEffect.Off;
            }
    
            private void OnUnderline(object sender, RoutedEventArgs e)
            {
                MenuFlyoutItem item = sender as MenuFlyoutItem;
                int x = Convert.ToInt32(item.Tag);
                UnderlineType unlinetp;
                switch (x)
                {
                    case -1: //
                        unlinetp = UnderlineType.None;
                        break;
                    case 0: // 单实线
                        unlinetp = UnderlineType.Single;
                        break;
                    case 1: // 双实线
                        unlinetp = UnderlineType.Double;
                        break;
                    case 2: // 虚线
                        unlinetp = UnderlineType.Dash;
                        break;
                    default:
                        unlinetp = UnderlineType.None;
                        break;
                }
                redit.Document.Selection.CharacterFormat.Underline = unlinetp;
            }

    运行应用程序,最终效果如下。

    OK,本次任务完成,3166。

    示例源代码下载

  • 相关阅读:
    Java 开发者不容错过的 12 种高效工具
    10个基于 Ruby on Rails 构建的顶级站点
    当 ITOA 遇上 OneAlert,企业可以至少每年节省 3600 小时!
    年度十佳 DevOps 博客文章(前篇)
    如何使用 Java8 实现观察者模式?(下)
    企业处理事件风暴的 2 种最佳管理方法
    移动开发:初学 iOS-UIViewController 心得
    如何使用 Java8 实现观察者模式?(上)
    世界级的安卓测试开发流!
    PHP全栈学习笔记19
  • 原文地址:https://www.cnblogs.com/tcjiaan/p/4937301.html
Copyright © 2011-2022 走看看