【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。

 

示例源代碼下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM