除了已有的弹出项目之外,是否可以向 UWP 中的 RichEditBox 添加菜单弹出项目。但我发现 richeditbox 中没有弹出属性。那么可以加一个吗?如果是,请提供添加 menuFlyout 的步骤。提前致谢!
最佳答案
当然有可能。
<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
触发。不知道为什么。那里
是 TextBox
的 ControlTemplate
中的 ScrollViewer
(可能是
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
您无法添加到文本框的现有上下文菜单。要修改这里的上下文菜单是sample
关于xaml - 将 MenuFlyout 添加到 RichEditBox UWP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37807730/