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 usesTextRange.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 usesTextRange.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
干杯,亚历克斯