using System;
|
using System.Windows;
|
using System.Windows.Controls;
|
using System.Windows.Input;
|
using System.Windows.Media;
|
using System.Windows.Threading;
|
|
namespace UILib
|
{
|
/// <summary>
|
/// 支持失去焦点后保持选中状态的 TextBox
|
/// </summary>
|
public class KeepSelectionTextBox : TextBox
|
{
|
private int _cachedSelectionStart;
|
private int _cachedSelectionLength;
|
private Brush _focusedSelectionBrush;
|
private double _focusedOpacity;
|
|
static KeepSelectionTextBox()
|
{
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(KeepSelectionTextBox),
|
new FrameworkPropertyMetadata(typeof(KeepSelectionTextBox)));
|
}
|
|
public KeepSelectionTextBox()
|
{
|
// 默认的非聚焦选中样式
|
InactiveSelectionBrush = new SolidColorBrush(Color.FromArgb(180, 0, 122, 204)); // 淡蓝色
|
InactiveSelectionOpacity = 0.6;
|
|
LostKeyboardFocus += OnLostKeyboardFocus;
|
GotKeyboardFocus += OnGotKeyboardFocus;
|
}
|
|
/// <summary>失去焦点后的选中画刷</summary>
|
public Brush InactiveSelectionBrush { get; set; }
|
|
/// <summary>失去焦点后的透明度</summary>
|
public double InactiveSelectionOpacity { get; set; } = 0.5;
|
|
private void OnLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
|
{
|
if (SelectionLength > 0)
|
{
|
// 保存选中范围
|
_cachedSelectionStart = SelectionStart;
|
_cachedSelectionLength = SelectionLength;
|
|
// 保存原始样式
|
_focusedSelectionBrush = SelectionBrush;
|
_focusedOpacity = SelectionOpacity;
|
|
// 应用非聚焦样式
|
SelectionBrush = InactiveSelectionBrush;
|
SelectionOpacity = InactiveSelectionOpacity;
|
|
// 延迟恢复选中状态
|
Dispatcher.BeginInvoke(new Action(RestoreSelection),
|
DispatcherPriority.ContextIdle);
|
}
|
}
|
|
private void RestoreSelection()
|
{
|
if (_cachedSelectionLength > 0)
|
{
|
try
|
{
|
Select(_cachedSelectionStart, _cachedSelectionLength);
|
}
|
catch
|
{
|
// 忽略可能的异常(如文本已被修改)
|
}
|
}
|
}
|
|
private void OnGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
|
{
|
// 恢复原始样式
|
if (_focusedSelectionBrush != null)
|
{
|
SelectionBrush = _focusedSelectionBrush;
|
SelectionOpacity = _focusedOpacity;
|
}
|
|
// 可选:重新应用之前保存的选区
|
if (_cachedSelectionLength > 0)
|
{
|
Dispatcher.BeginInvoke(new Action(() =>
|
{
|
Select(_cachedSelectionStart, _cachedSelectionLength);
|
}), DispatcherPriority.Loaded);
|
}
|
}
|
}
|
}
|