【问题标题】:Adding MenuFlyout to a RichEditBox UWP将 MenuFlyout 添加到 RichEditBox UWP
【发布时间】:2016-06-14 09:15:00
【问题描述】:

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

【问题讨论】:

    标签: xaml win-universal-app uwp uwp-xaml richeditbox


    【解决方案1】:

    当然有可能。

     <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 触发。不知道为什么。那里 是ScrollViewerControlTemplate 中的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 并没有设置到确切的位置。

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

         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 上下文菜单中。要修改这里的上下文菜单是sample

    【讨论】:

    • 我想在光标位置附近显示它而不是 onfocus... 在右键单击时,我想将它与已有的弹出窗口(如剪切、复制、粘贴)一起显示。
    • 我认为弹出窗口不可能。您可能需要开发自己的
    • @KayKay 检查更新。我发布了自定义弹出的代码
    • 抱歉,我没有正确阅读您的问题。您想添加额外的菜单来已经呈现文本框弹出。其实它不是弹出,它的上下文菜单。参考这个链接code.msdn.microsoft.com/windowsapps/…
    • 但是您不能将您的菜单添加到现有菜单中。您必须自己创建它们。
    猜你喜欢
    • 2020-01-05
    • 2020-10-24
    • 1970-01-01
    • 1970-01-01
    • 2019-02-03
    • 1970-01-01
    • 2020-08-31
    • 2017-06-14
    • 2019-03-23
    相关资源
    最近更新 更多