alielie
2026-09-10 f3889f2d36c50cf99468594854def9b7ed069fb5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
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);
            }
        }
    }
}