Skip to content

Commit 01c50a8

Browse files
committedDec 11, 2024·
Wpf: Fix TextBox.Text so it clears the undo buffer when set
1 parent 4c99da5 commit 01c50a8

File tree

2 files changed

+65
-39
lines changed

2 files changed

+65
-39
lines changed
 

‎src/Eto.Wpf/Forms/Controls/TextBoxHandler.cs

+37-39
Original file line numberDiff line numberDiff line change
@@ -298,55 +298,53 @@ public string Text
298298
var oldText = Text;
299299
CurrentText = null;
300300
var newText = value ?? string.Empty;
301-
TextBox.BeginChange();
302-
if (newText != oldText)
303-
{
304-
var args = new TextChangingEventArgs(oldText, newText, false);
305-
Callback.OnTextChanging(Widget, args);
306-
if (args.Cancel)
307-
{
308-
TextBox.EndChange();
309-
return;
310-
}
301+
if (newText == oldText)
302+
return;
311303

312-
var needsTextChanged = TextBox.Text == newText;
304+
var args = new TextChangingEventArgs(oldText, newText, false);
305+
Callback.OnTextChanging(Widget, args);
306+
if (args.Cancel)
307+
return;
313308

314-
// Improve performance when setting text often
315-
// See https://github.com/dotnet/wpf/issues/5887#issuecomment-1604577981
316-
var endNoGCRegion = EnableNoGCRegion
317-
&& GCSettings.LatencyMode != GCLatencyMode.NoGCRegion;
309+
var needsTextChanged = TextBox.Text == newText;
318310

319-
try
320-
{
321-
endNoGCRegion &= GC.TryStartNoGCRegion(1000000); // is this magic number reasonable??
322-
}
323-
catch
324-
{
325-
// Ignore any exceptions, they can apparently still happen even though we check the LatencyMode above
326-
endNoGCRegion = false;
327-
}
311+
// Improve performance when setting text often
312+
// See https://github.com/dotnet/wpf/issues/5887#issuecomment-1604577981
313+
var endNoGCRegion = EnableNoGCRegion
314+
&& GCSettings.LatencyMode != GCLatencyMode.NoGCRegion;
328315

329-
try
330-
{
331-
TextBox.Text = newText;
332-
}
333-
finally
334-
{
335-
if (endNoGCRegion && GCSettings.LatencyMode == GCLatencyMode.NoGCRegion)
336-
GC.EndNoGCRegion();
337-
}
338-
339-
if (needsTextChanged)
340-
{
341-
Callback.OnTextChanged(Widget, EventArgs.Empty);
342-
}
316+
try
317+
{
318+
endNoGCRegion &= GC.TryStartNoGCRegion(1000000); // is this magic number reasonable??
343319
}
320+
catch
321+
{
322+
// Ignore any exceptions, they can apparently still happen even though we check the LatencyMode above
323+
endNoGCRegion = false;
324+
}
325+
326+
try
327+
{
328+
TextBox.Text = newText;
329+
}
330+
finally
331+
{
332+
if (endNoGCRegion && GCSettings.LatencyMode == GCLatencyMode.NoGCRegion)
333+
GC.EndNoGCRegion();
334+
}
335+
344336
if (value != null && AutoSelectMode == AutoSelectMode.Never && !HasFocus)
345337
{
338+
TextBox.BeginChange();
346339
TextBox.SelectionStart = value.Length;
347340
TextBox.SelectionLength = 0;
341+
TextBox.EndChange();
342+
}
343+
344+
if (needsTextChanged)
345+
{
346+
Callback.OnTextChanged(Widget, EventArgs.Empty);
348347
}
349-
TextBox.EndChange();
350348
}
351349
}
352350

‎test/Eto.Test/UnitTests/Forms/Controls/TextBoxTests.cs

+28
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,34 @@ namespace Eto.Test.UnitTests.Forms.Controls
66
public abstract class TextBoxBase<T> : TestBase
77
where T: TextBox, new()
88
{
9+
[Test, ManualTest]
10+
public void SettingTextShouldClearUndoBuffer()
11+
{
12+
ManualForm("Try typing and undo/redo, then press the button to reset. After reset, it should not undo to previous values", form =>
13+
{
14+
var textBox = new T();
15+
textBox.Text = "Hello";
16+
textBox.SelectAll();
17+
18+
var button = new Button { Text = "Click Me" };
19+
button.Click += (sender, e) =>
20+
{
21+
textBox.Text = "Thanks, now try to undo";
22+
textBox.Focus();
23+
};
24+
25+
return new TableLayout
26+
{
27+
Spacing = new Size(5, 5),
28+
Padding = 10,
29+
Rows = {
30+
textBox,
31+
button
32+
}
33+
};
34+
});
35+
}
36+
937
[Test, ManualTest]
1038
public void CaretIndexShouldStartInInitialPosition()
1139
{

0 commit comments

Comments
 (0)
Please sign in to comment.