1

除了已经可用的弹出项之外,是否可以向 UWP 中的 RichEditBox 添加菜单弹出项。但我看到richeditbox 中没有弹出属性。那么可以加一个吗?如果是,请提供添加 menuFlyout 的步骤。提前致谢!

4

1 回答 1

2

当然有可能。

 <RichEditBox GotFocus="RichEditBox_GotFocus">
                    <FlyoutBase.AttachedFlyout>
                        <Flyout>
                            <Button Content="test"/>
                        </Flyout>
                    </FlyoutBase.AttachedFlyout>
                </RichEditBox>

 private void RichEditBox_GotFocus(object sender, RoutedEventArgs e)
        {
            FlyoutBase.ShowAttachedFlyout((sender as RichEditBox));
        }

更新

我尝试在没有自定义弹出按钮的情况下实现您的要求。

观察

1 个RightTapped事件不会为Textbox. 不知道为什么。有ScrollViewer(可能这ControlTemplate就是TextBox文本框中没有触发 RightTapped 事件的原因)所以我为 Scrollviewer 添加了 RightTapped 事件。

2.

   private async void ContentElement_RightTapped(object sender, RightTappedRoutedEventArgs e)
            {
                FlyoutBase.ShowAttachedFlyout(textbox);
                 await  Task.Delay(1000);
                FlyoutPresenter canvas = testbutton.FindParent<FlyoutPresenter>();
                var popup = canvas.Parent as Popup;

                double x = e.GetPosition(e.OriginalSource as UIElement).X;
                Debug.WriteLine(x);
                popup.IsOpen = false;
                popup.SetValue(Canvas.LeftProperty, e.GetPosition(e.OriginalSource as  UIElement).X);
                popup.IsOpen = true;
            }


 <Style x:Key="RichEditBoxStyle1" TargetType="RichEditBox">
    ...
     <ScrollViewer x:Name="ContentElement" IsRightTapEnabled="True" RightTapped="ContentElement_RightTapped"  AutomationProperties.AccessibilityView="Raw" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="Disabled"/>
...
    </Style>
    <RichEditBox x:Name="textbox" Width="400" HorizontalAlignment="Left"  Grid.Row="3" RightTapped="RichEditBox_RightTapped" IsRightTapEnabled="True" GotFocus="RichEditBox_GotFocus" Style="{StaticResource RichEditBoxStyle1}">
                        <FlyoutBase.AttachedFlyout>
                               <Flyout >
                                <Button Content="test" x:Name="testbutton"            Click="Button_Click"/>   
                            </Flyout>
                        </FlyoutBase.AttachedFlyout>                        
                    </RichEditBox>

上面的代码 ContentElement_RightTapped是 ScrollViewer 的 RightTapped 事件。要添加这个您必须编辑文本框的样式。基本上,我正在使用 VisualTreeHelper 弹出弹出窗口。并设置 PopUp 的位置(我从事件中得到)。但不知何故,PopUp 并没有被设置到确切的位置。

所以第二种选择是进行自定义弹出。请参阅此链接了解如何实现一个。您可以从那里获取代码这是修改后的代码代码

     public class TemplatedFlyout:DependencyObject
        {
            public TemplatedFlyout()
            {

            }
            Popup popUp;
            FrameworkElement senderElement;
            FrameworkElement frameworkContent;
            bool keyboardOpen = false;
            InputPane keyboard;
            public void Initialization(UIElement sender)
            {
                senderElement = sender as FrameworkElement;
                senderElement.DataContextChanged += (s, e) =>frameworkContent.DataContext = senderElement.DataContext;
                popUp = new Popup()
                {
                    ChildTransitions = new Windows.UI.Xaml.Media.Animation.TransitionCollection(),
                    IsLightDismissEnabled = true
                };
                popUp.ChildTransitions.Add(new PaneThemeTransition() { Edge = EdgeTransitionLocation.Bottom });
                frameworkContent = Template as FrameworkElement;
                frameworkContent.DataContext = senderElement.DataContext;
                popUp.Child = frameworkContent;
                FocusKeeper();
             if(sender is RichEditBox || sender is TextBox)
                {
                    (sender as FrameworkElement).Loaded += TemplatedFlyout_Loaded;
                }
             //else
             //       sender.Tapped += (s, e) => Show(e);
            }

            private void TemplatedFlyout_Loaded(object sender, RoutedEventArgs e)
            {
                (sender as FrameworkElement).FindElementInVisualTree<ScrollViewer>().RightTapped += (s, e1) => Show(e1);
            }

           public static readonly DependencyProperty TemplateProperty = DependencyProperty.Register(nameof(Template), typeof(object), typeof(TemplatedFlyout), new PropertyMetadata(null));
            public object Template
            {
                get { return (object) GetValue(TemplateProperty); }
                set { SetValue(TemplateProperty, value); }
            }       
             void FocusKeeper()
            {
                keyboard = InputPane.GetForCurrentView();
                popUp.Closed += (s, e) =>
                {
                    if(keyboardOpen)
                    {
                        popUp.IsOpen = true;
                    }
                };
                if(keyboard!=null)
                {
                    keyboard.Showing += (s, e) => keyboardOpen = true;
                    keyboard.Hiding += (s, e) => keyboardOpen = false;
                }
            }
            public async void Show(RightTappedRoutedEventArgs args)
            {
                try
                {
                   popUp.RequestedTheme = ((Window.Current.Content as Frame).Content as Page).RequestedTheme;
                    popUp.IsOpen = true;
                    frameworkContent.UpdateLayout();
                    var top = Math.Abs(senderElement.ActualHeight+frameworkContent.ActualHeight+10-Window.Current.Bounds.Height);
                    var left = args.GetPosition(args.OriginalSource as UIElement).X;                
                    if (frameworkContent is Panel)
                    {
                        var panel = frameworkContent as Panel;
                        if (panel.Children.Any())
                        {
                            if (panel.Children.First() is Control)
                            {
                                (panel.Children.First() as Control).Focus(FocusState.Keyboard);
                            }
                        }
                    }                
                    popUp.SetValue(Canvas.TopProperty, top);
                    popUp.SetValue(Canvas.LeftProperty, left);

                }
                catch(Exception e)
                {

                }
            }       
        }

  public class Extensions:DependencyObject
    {

        public static void SetFlyout(UIElement element, TemplatedFlyout value)
        {
            element.SetValue(FlyoutProperty, value);
        }
        public static TemplatedFlyout GetFlyout(UIElement element)
        {
            return (TemplatedFlyout)element.GetValue(FlyoutProperty);
        }
        public static readonly DependencyProperty FlyoutProperty = DependencyProperty.Register(nameof(FlyoutProperty), typeof(TemplatedFlyout), typeof(Extensions), new PropertyMetadata(null, TemplateFlyoutChanged));

        private static void TemplateFlyoutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var uiSender = d as UIElement;
            var flyout = e.NewValue as TemplatedFlyout;
            flyout.Initialization(uiSender);
        }
    }
    public static class VisualExtensions
    {       
        public static T FindElementInVisualTree<T>(this DependencyObject parentElement) where T : DependencyObject
        {
            var count = VisualTreeHelper.GetChildrenCount(parentElement);
            if (count == 0) return null;

            for (int i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(parentElement, i);
                if (child != null && child is T)
                    return (T)child;
                else
                {
                    var result = FindElementInVisualTree<T>(child);
                    if (result != null)
                        return result;
                }
            }
            return null;
        }
    }


<RichEditBox  IsRightTapEnabled="True"  >
                <local:Extensions.Flyout>
                    <local:TemplatedFlyout >
                        <local:TemplatedFlyout.Template>
                            <StackPanel>
                                <TextBlock Text="test1"/>
                                <TextBlock Text="test1"/>
                            </StackPanel>
                        </local:TemplatedFlyout.Template>
                    </local:TemplatedFlyout>
                </local:Extensions.Flyout>
            </RichEditBox>

更新 2

您不能添加到现有的 TextBox 上下文菜单。要修改上下文菜单,这里是示例

于 2016-06-14T10:16:32.013 回答