有人知道如何在RichEditBox中保持所选文本的视觉选择状态吗?我想在我的Windows 8.1应用程序中添加一些基本的文本编辑,但每次选择文本并单击应用程序中的另一个UI元素时,RichEditBox都会隐藏选择。
我已经尝试注册非聚焦事件,再次设置选择范围,但不幸的是,这没有效果。
我还尝试使用
在Text上绘制自己的rectrichEdit.Document.Selection.GetRect(PointOptions.ClientCoordinates,out selectionRect, out hitCount );
只要选择了一行中的某些文本,就可以正常工作。如果选择是多行的,我只获得所选文本的左上角和右下角。看起来这些是鼠标位置选择开始位置和结束位置。
当RichEditBox未聚焦时,还有其他方法可以保持所选文本的可见性。
答案 0 :(得分:1)
我发现了另一种解决方法。只需在RichEditBox未聚焦时设置选择背景。但是Jerry的帖子给了我这个解决方案的灵感。似乎这样简单地找到它是第一位的:
private void RichEditOnGotFocus(object sender, RoutedEventArgs routedEventArgs)
{
ITextSelection selectedText = richEdit.Document.Selection;
if (selectedText != null)
{
richEdit.Document.Selection.SetRange(_selectionStart, _selectionEnd);
selectedText.CharacterFormat.BackgroundColor = Colors.White;
}
}
private void RichEditOnLostFocus(object sender, RoutedEventArgs routedEventArgs)
{
_selectionEnd = richEdit.Document.Selection.EndPosition;
_selectionStart = richEdit.Document.Selection.StartPosition;
ITextSelection selectedText = richEdit.Document.Selection;
if (selectedText != null)
{
selectedText.CharacterFormat.BackgroundColor = Colors.Gray;
}
}
答案 1 :(得分:0)
在WinRT工具包中,有一个HighlightBehavior并没有直接解决您的问题,但可能会为您提供一个可接受的解决方案。
public class HighlightBehavior : Behavior<TextBlock>
{
#region SearchString
/// <summary>
/// SearchString Dependency Property
/// </summary>
public static readonly DependencyProperty SearchStringProperty =
DependencyProperty.Register(
"SearchString",
typeof(string),
typeof(HighlightBehavior),
new PropertyMetadata(null, OnSearchStringChanged));
/// <summary>
/// Gets or sets the SearchString property. This dependency property
/// indicates the search string to highlight in the associated TextBlock.
/// </summary>
public string SearchString
{
get { return (string)GetValue(SearchStringProperty); }
set { SetValue(SearchStringProperty, value); }
}
/// <summary>
/// Handles changes to the SearchString property.
/// </summary>
/// <param name="d">
/// The <see cref="DependencyObject"/> on which
/// the property has changed value.
/// </param>
/// <param name="e">
/// Event data that is issued by any event that
/// tracks changes to the effective value of this property.
/// </param>
private static void OnSearchStringChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = (HighlightBehavior)d;
string oldSearchString = (string)e.OldValue;
string newSearchString = target.SearchString;
target.OnSearchStringChanged(oldSearchString, newSearchString);
}
/// <summary>
/// Provides derived classes an opportunity to handle changes
/// to the SearchString property.
/// </summary>
/// <param name="oldSearchString">The old SearchString value</param>
/// <param name="newSearchString">The new SearchString value</param>
private void OnSearchStringChanged(
string oldSearchString, string newSearchString)
{
UpdateHighlight();
}
#endregion
#region IsCaseSensitive
/// <summary>
/// IsCaseSensitive Dependency Property
/// </summary>
public static readonly DependencyProperty IsCaseSensitiveProperty =
DependencyProperty.Register(
"IsCaseSensitive",
typeof(bool),
typeof(HighlightBehavior),
new PropertyMetadata(false, OnIsCaseSensitiveChanged));
/// <summary>
/// Gets or sets the IsCaseSensitive property. This dependency property
/// indicates whether the highlight behavior is case sensitive.
/// </summary>
public bool IsCaseSensitive
{
get { return (bool)GetValue(IsCaseSensitiveProperty); }
set { SetValue(IsCaseSensitiveProperty, value); }
}
/// <summary>
/// Handles changes to the IsCaseSensitive property.
/// </summary>
/// <param name="d">
/// The <see cref="DependencyObject"/> on which
/// the property has changed value.
/// </param>
/// <param name="e">
/// Event data that is issued by any event that
/// tracks changes to the effective value of this property.
/// </param>
private static void OnIsCaseSensitiveChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = (HighlightBehavior)d;
bool oldIsCaseSensitive = (bool)e.OldValue;
bool newIsCaseSensitive = target.IsCaseSensitive;
target.OnIsCaseSensitiveChanged(oldIsCaseSensitive, newIsCaseSensitive);
}
/// <summary>
/// Provides derived classes an opportunity to handle changes
/// to the IsCaseSensitive property.
/// </summary>
/// <param name="oldIsCaseSensitive">The old IsCaseSensitive value</param>
/// <param name="newIsCaseSensitive">The new IsCaseSensitive value</param>
private void OnIsCaseSensitiveChanged(
bool oldIsCaseSensitive, bool newIsCaseSensitive)
{
UpdateHighlight();
}
#endregion
#region HighlightTemplate
/// <summary>
/// HighlightTemplate Dependency Property
/// </summary>
public static readonly DependencyProperty HighlightTemplateProperty =
DependencyProperty.Register(
"HighlightTemplate",
typeof(DataTemplate),
typeof(HighlightBehavior),
new PropertyMetadata(null, OnHighlightTemplateChanged));
/// <summary>
/// Gets or sets the HighlightTemplate property. This dependency property
/// indicates the template to use to generate the highlight Run inlines.
/// </summary>
public DataTemplate HighlightTemplate
{
get { return (DataTemplate)GetValue(HighlightTemplateProperty); }
set { SetValue(HighlightTemplateProperty, value); }
}
/// <summary>
/// Handles changes to the HighlightTemplate property.
/// </summary>
/// <param name="d">
/// The <see cref="DependencyObject"/> on which
/// the property has changed value.
/// </param>
/// <param name="e">
/// Event data that is issued by any event that
/// tracks changes to the effective value of this property.
/// </param>
private static void OnHighlightTemplateChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = (HighlightBehavior)d;
DataTemplate oldHighlightTemplate = (DataTemplate)e.OldValue;
DataTemplate newHighlightTemplate = target.HighlightTemplate;
target.OnHighlightTemplateChanged(oldHighlightTemplate, newHighlightTemplate);
}
/// <summary>
/// Provides derived classes an opportunity to handle changes
/// to the HighlightTemplate property.
/// </summary>
/// <param name="oldHighlightTemplate">The old HighlightTemplate value</param>
/// <param name="newHighlightTemplate">The new HighlightTemplate value</param>
private void OnHighlightTemplateChanged(
DataTemplate oldHighlightTemplate, DataTemplate newHighlightTemplate)
{
UpdateHighlight();
}
#endregion
#region HighlightBrush
/// <summary>
/// HighlightBrush Dependency Property
/// </summary>
public static readonly DependencyProperty HighlightBrushProperty =
DependencyProperty.Register(
"HighlightBrush",
typeof(Brush),
typeof(HighlightBehavior),
new PropertyMetadata(new SolidColorBrush(Colors.Red), OnHighlightBrushChanged));
/// <summary>
/// Gets or sets the HighlightBrush property. This dependency property
/// indicates the brush to use to highlight the found instances of the search string.
/// </summary>
/// <remarks>
/// Note that the brush is ignored if HighlightTemplate is specified
/// </remarks>
public Brush HighlightBrush
{
get { return (Brush)GetValue(HighlightBrushProperty); }
set { SetValue(HighlightBrushProperty, value); }
}
/// <summary>
/// Handles changes to the HighlightBrush property.
/// </summary>
/// <param name="d">
/// The <see cref="DependencyObject"/> on which
/// the property has changed value.
/// </param>
/// <param name="e">
/// Event data that is issued by any event that
/// tracks changes to the effective value of this property.
/// </param>
private static void OnHighlightBrushChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = (HighlightBehavior)d;
Brush oldHighlightBrush = (Brush)e.OldValue;
Brush newHighlightBrush = target.HighlightBrush;
target.OnHighlightBrushChanged(oldHighlightBrush, newHighlightBrush);
}
/// <summary>
/// Provides derived classes an opportunity to handle changes
/// to the HighlightBrush property.
/// </summary>
/// <param name="oldHighlightBrush">The old HighlightBrush value</param>
/// <param name="newHighlightBrush">The new HighlightBrush value</param>
private void OnHighlightBrushChanged(
Brush oldHighlightBrush, Brush newHighlightBrush)
{
UpdateHighlight();
}
#endregion
private PropertyChangeEventSource<string> _textChangeEventSource;
/// <summary>
/// Called after the behavior is attached to an AssociatedObject.
/// </summary>
/// <remarks>
/// Override this to hook up functionality to the AssociatedObject.
/// </remarks>
protected override void OnAttached()
{
UpdateHighlight();
_textChangeEventSource = new PropertyChangeEventSource<string>(this.AssociatedObject, "Text", BindingMode.OneWay);
_textChangeEventSource.ValueChanged += TextChanged;
base.OnAttached();
}
/// <summary>
/// Called when the behavior is being detached from its AssociatedObject, but
/// before it has actually occurred.
/// </summary>
/// <remarks>
/// Override this to unhook functionality from the AssociatedObject.
/// </remarks>
protected override void OnDetaching()
{
ClearHighlight();
_textChangeEventSource.ValueChanged -= TextChanged;
_textChangeEventSource = null;
base.OnDetaching();
}
private void TextChanged(object sender, string s)
{
UpdateHighlight();
}
/// <summary>
/// Updates the highlight.
/// </summary>
public void UpdateHighlight()
{
if (this.AssociatedObject == null ||
string.IsNullOrEmpty(this.AssociatedObject.Text) ||
string.IsNullOrEmpty(this.SearchString))
{
ClearHighlight();
return;
}
var txt = this.AssociatedObject.Text;
var searchTxt = this.SearchString;
var processedCharacters = 0;
this.AssociatedObject.Inlines.Clear();
int pos;
while ((pos = txt.IndexOf(
searchTxt,
processedCharacters,
this.IsCaseSensitive ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase)) >= 0)
{
if (pos > processedCharacters)
{
var run = new Run
{
Text =
txt.Substring(
processedCharacters, pos - processedCharacters)
};
this.AssociatedObject.Inlines.Add(run);
}
Run highlight;
var highlightText = txt.Substring(pos, searchTxt.Length);
if (this.HighlightTemplate == null)
{
highlight =
new Run
{
Text = highlightText,
Foreground = this.HighlightBrush
};
}
else
{
highlight = (Run)this.HighlightTemplate.LoadContent();
highlight.Text = highlightText;
}
this.AssociatedObject.Inlines.Add(highlight);
processedCharacters = pos + searchTxt.Length;
}
if (processedCharacters < txt.Length)
{
var run = new Run
{
Text =
txt.Substring(
processedCharacters, txt.Length - processedCharacters)
};
this.AssociatedObject.Inlines.Add(run);
}
}
/// <summary>
/// Clears the highlight.
/// </summary>
public void ClearHighlight()
{
if (this.AssociatedObject == null)
{
return;
}
var text = this.AssociatedObject.Text;
this.AssociatedObject.Inlines.Clear();
this.AssociatedObject.Inlines.Add(new Run{Text = text});
}
}
public abstract class Behavior<T> : Behavior where T : DependencyObject
{
#region Behavior() - CTOR
/// <summary>
/// Initializes a new instance of the <see cref="Behavior<T>"/> class.
/// </summary>
protected Behavior()
{
_associatedType = typeof(T);
}
#endregion
#region AssociatedObject
/// <summary>
/// Gets the object to which this <see cref="Behavior<T>" /> is attached.
/// </summary>
public new T AssociatedObject
{
get
{
return (T)_associatedObject;
}
internal set
{
_associatedObject = value;
}
}
#endregion
}
祝你好运!