.NET MAUI Editor控件文本选择检测与操作功能实现咨询
.NET MAUI Editor文本选择检测与内容获取方案
针对.NET MAUI构建文字处理器时的文本选择需求,无需使用已过时的旧版渲染器,官方推荐用Handlers替代实现跨平台的文本选择监听与内容提取,以下是具体实现方案:
1. 自定义可选择Editor控件
先创建带选择属性的自定义Editor,方便后续绑定和获取选择信息:
using Microsoft.Maui.Controls; namespace YourAppNamespace; public class SelectableEditor : Editor { public static readonly BindableProperty SelectedTextProperty = BindableProperty.Create(nameof(SelectedText), typeof(string), typeof(SelectableEditor), string.Empty); public static readonly BindableProperty SelectionStartProperty = BindableProperty.Create(nameof(SelectionStart), typeof(int), typeof(SelectableEditor), 0); public static readonly BindableProperty SelectionLengthProperty = BindableProperty.Create(nameof(SelectionLength), typeof(int), typeof(SelectableEditor), 0); public string SelectedText { get => (string)GetValue(SelectedTextProperty); set => SetValue(SelectedTextProperty, value); } public int SelectionStart { get => (int)GetValue(SelectionStartProperty); set => SetValue(SelectionStartProperty, value); } public int SelectionLength { get => (int)GetValue(SelectionLengthProperty); set => SetValue(SelectionLengthProperty, value); } }
2. 各平台Handler实现
Windows平台(核心目标平台)
Windows下Editor映射为TextBox,监听SelectionChanged事件同步选择信息:
using Microsoft.Maui.Platform; using Microsoft.UI.Xaml.Controls; namespace YourAppNamespace.Platforms.Windows; public static class SelectableEditorHandlerExtensions { public static void ConfigureSelectableEditor(this IMauiHandlersCollection handlers) { handlers.AddHandler<SelectableEditor, SelectableEditorHandler>(); } } public class SelectableEditorHandler : EditorHandler { protected override void ConnectHandler(TextBox platformView) { base.ConnectHandler(platformView); platformView.SelectionChanged += OnSelectionChanged; } protected override void DisconnectHandler(TextBox platformView) { platformView.SelectionChanged -= OnSelectionChanged; base.DisconnectHandler(platformView); } private void OnSelectionChanged(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { if (sender is TextBox textBox && VirtualView is SelectableEditor editor) { editor.SelectedText = textBox.SelectedText; editor.SelectionStart = textBox.SelectionStart; editor.SelectionLength = textBox.SelectionLength; } } }
Android平台
Android下Editor映射为EditText,通过OnSelectionChangeListener监听选择变化:
using Android.Widget; using Microsoft.Maui.Platform; namespace YourAppNamespace.Platforms.Android; public static class SelectableEditorHandlerExtensions { public static void ConfigureSelectableEditor(this IMauiHandlersCollection handlers) { handlers.AddHandler<SelectableEditor, SelectableEditorHandler>(); } } public class SelectableEditorHandler : EditorHandler { private TextView.IOnSelectionChangeListener _selectionListener; protected override void ConnectHandler(EditText platformView) { base.ConnectHandler(platformView); _selectionListener = new SelectionChangeListener(VirtualView as SelectableEditor); platformView.SetOnSelectionChangeListener(_selectionListener); } protected override void DisconnectHandler(EditText platformView) { platformView.SetOnSelectionChangeListener(null); _selectionListener.Dispose(); base.DisconnectHandler(platformView); } private class SelectionChangeListener : Java.Lang.Object, TextView.IOnSelectionChangeListener { private readonly SelectableEditor _editor; public SelectionChangeListener(SelectableEditor editor) { _editor = editor; } public void OnSelectionChanged(TextView textView, int start, int end) { _editor.SelectedText = textView.Text.Substring(start, end - start); _editor.SelectionStart = start; _editor.SelectionLength = end - start; } } }
iOS平台
iOS下Editor映射为UITextView,通过自定义UITextViewDelegate监听选择变化:
using Foundation; using Microsoft.Maui.Platform; using UIKit; namespace YourAppNamespace.Platforms.iOS; public static class SelectableEditorHandlerExtensions { public static void ConfigureSelectableEditor(this IMauiHandlersCollection handlers) { handlers.AddHandler<SelectableEditor, SelectableEditorHandler>(); } } public class SelectableEditorHandler : EditorHandler { private CustomTextViewDelegate _customDelegate; protected override void ConnectHandler(UITextView platformView) { base.ConnectHandler(platformView); _customDelegate = new CustomTextViewDelegate(VirtualView as SelectableEditor); platformView.Delegate = _customDelegate; } protected override void DisconnectHandler(UITextView platformView) { platformView.Delegate = null; _customDelegate.Dispose(); base.DisconnectHandler(platformView); } private class CustomTextViewDelegate : UITextViewDelegate { private readonly SelectableEditor _editor; public CustomTextViewDelegate(SelectableEditor editor) { _editor = editor; } public override void SelectionChanged(UITextView textView) { base.SelectionChanged(textView); var selectedRange = textView.SelectedRange; _editor.SelectedText = textView.Text.Substring((int)selectedRange.Location, (int)selectedRange.Length); _editor.SelectionStart = (int)selectedRange.Location; _editor.SelectionLength = (int)selectedRange.Length; } } }
3. 注册Handler并使用
在MauiProgram.cs中注册各平台Handler:
builder.ConfigureMauiHandlers(handlers => { #if WINDOWS handlers.ConfigureSelectableEditor(); #elif ANDROID handlers.ConfigureSelectableEditor(); #elif IOS handlers.ConfigureSelectableEditor(); #endif });
在XAML中使用自定义控件并实现功能:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:YourAppNamespace" x:Class="YourAppNamespace.MainPage"> <VerticalStackLayout Padding="20"> <local:SelectableEditor x:Name="MyEditor" HeightRequest="200" Placeholder="输入并选中文本..." /> <Label Text="选中的文本:" Margin="0,10,0,0" /> <Label Text="{Binding SelectedText, Source={x:Reference MyEditor}}" /> <Button Text="复制到剪贴板" Clicked="CopySelected_Clicked" Margin="0,10,0,0" /> <Button Text="标记选中文本为粗体" Clicked="BoldSelected_Clicked" /> </VerticalStackLayout> </ContentPage>
后台代码实现剪贴板和格式设置逻辑:
private async void CopySelected_Clicked(object sender, EventArgs e) { if (!string.IsNullOrEmpty(MyEditor.SelectedText)) { await Clipboard.SetTextAsync(MyEditor.SelectedText); } } private void BoldSelected_Clicked(object sender, EventArgs e) { if (MyEditor.SelectionLength <= 0) return; // 示例:给选中文本前后添加Markdown粗体标记 var fullText = MyEditor.Text; var newText = fullText.Insert(MyEditor.SelectionStart + MyEditor.SelectionLength, "**") .Insert(MyEditor.SelectionStart, "**"); MyEditor.Text = newText; // 恢复选中范围(可选) MyEditor.SelectionStart = MyEditor.SelectionStart; MyEditor.SelectionLength = MyEditor.SelectedText.Length + 4; }
注意事项
- 该方案基于.NET MAUI官方推荐的Handlers模式,完全兼容最新版本,替代了已过时的渲染器方案。
- 跨平台兼容:Windows/Android/iOS均已实现,macOS可参考iOS逻辑适配。
- 若需实现真正的富文本格式(如字体颜色、字号),可基于原生控件扩展,Editor控件仅适用于纯文本或标记类文本处理。
内容的提问来源于stack exchange,提问作者coyotesword
相关产品推荐
相关产品推荐

