-
Notifications
You must be signed in to change notification settings - Fork 4
/
TextBoxFinder.cs
174 lines (142 loc) · 4.59 KB
/
TextBoxFinder.cs
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
namespace Menees.Windows.Forms
{
#region Using Directives
using System;
using System.Windows.Forms;
#endregion
/// <summary>
/// Handles Find opertions for a TextBox.
/// </summary>
public class TextBoxFinder : Finder
{
#region Private Data Members
private TextBoxBase textBox;
#endregion
#region Constructors
/// <summary>
/// Creates a new instance.
/// </summary>
/// <param name="textBox">The <see cref="System.Windows.Forms.TextBox"/>
/// or <see cref="RichTextBox"/> control to search in.</param>
public TextBoxFinder(TextBoxBase textBox)
{
this.TextBox = textBox;
this.textBox = this.TextBox; // Satisfy C# compiler that this.textBox was set.
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the TextBoxBase to search in.
/// </summary>
public TextBoxBase TextBox
{
get
{
return this.textBox;
}
set
{
Conditions.RequireReference(value, nameof(value));
this.textBox = value;
}
}
#endregion
#region Protected Overrides
/// <summary>
/// Handles displaying the find dialog.
/// </summary>
/// <param name="findDialog">The dialog to display.</param>
/// <param name="owner">The dialog owner.</param>
/// <param name="findData">The find data.</param>
/// <returns>True if the user pressed OK.</returns>
protected override bool OnDialogExecute(IFindDialog findDialog, IWin32Window owner, FindData findData)
{
// Initialize the find text from the selection.
string? oldFindText = null;
if (this.textBox.SelectionLength > 0)
{
// Only use the selection if it is one line or less.
string selectedText = this.textBox.SelectedText;
if (selectedText.IndexOf('\n') < 0)
{
oldFindText = findData.Text;
findData.Text = this.textBox.SelectedText;
}
}
// Call the base method to display the dialog.
bool result = base.OnDialogExecute(findDialog, owner, findData);
// If they canceled, then we may need to restore the old find text.
if (!result && oldFindText != null)
{
findData.Text = oldFindText;
}
return result;
}
/// <summary>
/// Finds the next instance.
/// </summary>
protected override bool OnFindNext()
{
StringComparison comparison = this.GetStrings(out string findText, out string editText);
// Search from the starting position to the end.
int startingPosition = this.textBox.SelectionStart + this.textBox.SelectionLength;
int findIndex = editText.IndexOf(findText, startingPosition, comparison);
if (findIndex < 0)
{
// If not found, then search from the beginning to the starting position plus up to
// FindText.Length extra characters in case the caret is already inside the match text.
int count = Math.Min(startingPosition + findText.Length, editText.Length);
findIndex = editText.IndexOf(findText, 0, count, comparison);
}
bool result = this.HandleFindIndex(findIndex);
return result;
}
/// <summary>
/// Finds the previous instance.
/// </summary>
protected override bool OnFindPrevious()
{
StringComparison comparison = this.GetStrings(out string findText, out string editText);
// Search from before the starting position to the beginning. LastIndexOf includes
// the starting index position in its search, so we need to subtract one.
int startingPosition = this.textBox.SelectionStart - 1;
int findIndex = startingPosition >= 0 ? editText.LastIndexOf(findText, startingPosition, comparison) : -1;
if (findIndex < 0)
{
// If not found, then search from the end to the starting position plus up to
// FindText.Length extra characters in case the caret is already inside the match text.
int lastIndex = editText.Length;
int count = Math.Min(lastIndex - startingPosition + findText.Length, lastIndex);
findIndex = editText.LastIndexOf(findText, lastIndex, count, comparison);
}
bool result = this.HandleFindIndex(findIndex);
return result;
}
#endregion
#region Private Methods
private StringComparison GetStrings(out string findText, out string editText)
{
findText = this.Data.Text;
editText = this.textBox.Text;
StringComparison result = this.Data.MatchCase ? StringComparison.CurrentCulture : StringComparison.CurrentCultureIgnoreCase;
return result;
}
private bool HandleFindIndex(int findIndex)
{
bool result = false;
if (findIndex >= 0)
{
this.textBox.SelectionStart = findIndex;
this.textBox.SelectionLength = this.Data.Text.Length;
this.textBox.ScrollToCaret();
result = true;
}
else
{
this.Data.ReportNotFound(this.textBox);
}
return result;
}
#endregion
}
}