如何在WPF文本框中选择多个文本段?

时间:2022-06-08 21:12:35

Is it possible to select multiple parts of text within a WPF textbox? For instance, for a textbox that contains the string THIS IS A TEST, I want to be able to highlight THIS, then hold Ctrl and highlight TEST without unselecting THIS.

是否可以在WPF文本框中选择文本的多个部分?例如,对于包含字符串这是一个测试的文本框,我希望能够高亮显示这个,然后按住Ctrl并突出测试,而不需要取消选择。

For a visual clue about what I'm aiming at, see this article about the feature in Firefox.

要了解我的目标是什么,请参阅本文关于Firefox特性的文章。

If by default there is no way to accomplish this, I would like to know if there is any third-party control implemented in WPF that does.

如果默认情况下没有办法实现这一点,我想知道在WPF中是否实现了任何第三方控件。

2 个解决方案

#1


13  

WPF's TextBox and RichTextBox classes do not directly support multiselection, but as with most parts of WPF it's extremely easy to customize its existing RichTextBox to get this ability.

WPF的文本框和RichTextBox类不直接支持多选择,但与WPF的大多数部分一样,它可以非常容易地定制现有的RichTextBox来获得这种能力。

The steps are:

的步骤是:

  • Create a class deriving from RichTextBox
  • 创建一个从RichTextBox派生的类
  • Add an "AdditionalRanges" property of type ObservableCollection<TextRange> which will contain all selected ranges except the current TextSelection
  • 添加类型ObservableCollection 的“AdditionalRanges”属性,该属性将包含除当前文本选择之外的所有选定范围
  • Override OnPreviewMouseLeftButtonDown: If Ctrl is pressed, combine the current TextSelection into your "AdditionalRanges" property and clear Selection, otherwise clear "AdditionalRanges".
  • 覆盖OnPreviewMouseLeftButtonDown:如果按下Ctrl,将当前的TextSelection合并到“AdditionalRanges”属性和清除选择,否则将清除“AdditionalRanges”。
  • In the constructor, add a CollectionChanged handler to "AdditionalRanges" that uses TextRange.ApplyPropertyValue() to make added ranges in the collection appear hilighted and removed ranges appear normally.
  • 在构造函数中,向“AdditionalRanges”添加一个CollectionChanged处理程序,该处理程序使用textrang . applypropertyvalue()使集合中添加的范围显示为有组织的,删除的范围显示为正常。

In your implementation I also recommend you implement a few more properties for convenience:

在您的实现中,我还建议您实现一些更方便的属性:

  • An "AllRanges" property that combines the TextSelection with AdditionalRanges
  • 一个“AllRanges”属性,它将TextSelection和AdditionalRanges结合在一起
  • A bindable "Text" property
  • 一个绑定“文本”属性
  • A bindable "SelectedText" property
  • 绑定“SelectedText”属性

These are all quite trivial to implement.

这些都是很容易实现的。

Final notes:

最后指出:

  • When updating AdditionalRanges or computing AllRanges, if the TextSelection overlaps an existing AdditionalRange, replace it with a combined range otherwise add the TextSelection to the list.
  • 当更新AdditionalRanges或计算AllRanges时,如果TextSelection与现有的AdditionalRange重叠,则将其替换为一个组合的range,否则将向列表添加TextSelection。
  • You can add a TextChanged handler to know when to update the "Text" property, and a PropertyChangedCallback to know when to update the FlowDocument
  • 您可以添加一个TextChanged处理程序以知道何时更新“Text”属性,以及一个PropertyChangedCallback以知道何时更新FlowDocument

#2


2  

the standard WPF TextBox does not support such behaviour, unfortunately. So the only way I see to get that functionality would be implementing your own text box control (maybe based on the standard text box ControlTemplate).

不幸的是,标准WPF文本框不支持这种行为。因此,我看到的获得这个功能的唯一方法是实现您自己的文本框控件(可能基于标准的文本框控件模板)。

Cheers, Alex

干杯,亚历克斯

#1


13  

WPF's TextBox and RichTextBox classes do not directly support multiselection, but as with most parts of WPF it's extremely easy to customize its existing RichTextBox to get this ability.

WPF的文本框和RichTextBox类不直接支持多选择,但与WPF的大多数部分一样,它可以非常容易地定制现有的RichTextBox来获得这种能力。

The steps are:

的步骤是:

  • Create a class deriving from RichTextBox
  • 创建一个从RichTextBox派生的类
  • Add an "AdditionalRanges" property of type ObservableCollection<TextRange> which will contain all selected ranges except the current TextSelection
  • 添加类型ObservableCollection 的“AdditionalRanges”属性,该属性将包含除当前文本选择之外的所有选定范围
  • Override OnPreviewMouseLeftButtonDown: If Ctrl is pressed, combine the current TextSelection into your "AdditionalRanges" property and clear Selection, otherwise clear "AdditionalRanges".
  • 覆盖OnPreviewMouseLeftButtonDown:如果按下Ctrl,将当前的TextSelection合并到“AdditionalRanges”属性和清除选择,否则将清除“AdditionalRanges”。
  • In the constructor, add a CollectionChanged handler to "AdditionalRanges" that uses TextRange.ApplyPropertyValue() to make added ranges in the collection appear hilighted and removed ranges appear normally.
  • 在构造函数中,向“AdditionalRanges”添加一个CollectionChanged处理程序,该处理程序使用textrang . applypropertyvalue()使集合中添加的范围显示为有组织的,删除的范围显示为正常。

In your implementation I also recommend you implement a few more properties for convenience:

在您的实现中,我还建议您实现一些更方便的属性:

  • An "AllRanges" property that combines the TextSelection with AdditionalRanges
  • 一个“AllRanges”属性,它将TextSelection和AdditionalRanges结合在一起
  • A bindable "Text" property
  • 一个绑定“文本”属性
  • A bindable "SelectedText" property
  • 绑定“SelectedText”属性

These are all quite trivial to implement.

这些都是很容易实现的。

Final notes:

最后指出:

  • When updating AdditionalRanges or computing AllRanges, if the TextSelection overlaps an existing AdditionalRange, replace it with a combined range otherwise add the TextSelection to the list.
  • 当更新AdditionalRanges或计算AllRanges时,如果TextSelection与现有的AdditionalRange重叠,则将其替换为一个组合的range,否则将向列表添加TextSelection。
  • You can add a TextChanged handler to know when to update the "Text" property, and a PropertyChangedCallback to know when to update the FlowDocument
  • 您可以添加一个TextChanged处理程序以知道何时更新“Text”属性,以及一个PropertyChangedCallback以知道何时更新FlowDocument

#2


2  

the standard WPF TextBox does not support such behaviour, unfortunately. So the only way I see to get that functionality would be implementing your own text box control (maybe based on the standard text box ControlTemplate).

不幸的是,标准WPF文本框不支持这种行为。因此,我看到的获得这个功能的唯一方法是实现您自己的文本框控件(可能基于标准的文本框控件模板)。

Cheers, Alex

干杯,亚历克斯