Skip to content

Commit

Permalink
Merge pull request #2713 from cwensley/curtis/wpf-fix-textbox-undo-bu…
Browse files Browse the repository at this point in the history
…ffer

Wpf: Fix TextBox.Text so it clears the undo buffer when set
  • Loading branch information
cwensley authored Dec 11, 2024
2 parents 4c99da5 + 01c50a8 commit 24b8fa6
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 39 deletions.
76 changes: 37 additions & 39 deletions src/Eto.Wpf/Forms/Controls/TextBoxHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -298,55 +298,53 @@ public string Text
var oldText = Text;
CurrentText = null;
var newText = value ?? string.Empty;
TextBox.BeginChange();
if (newText != oldText)
{
var args = new TextChangingEventArgs(oldText, newText, false);
Callback.OnTextChanging(Widget, args);
if (args.Cancel)
{
TextBox.EndChange();
return;
}
if (newText == oldText)
return;

var needsTextChanged = TextBox.Text == newText;
var args = new TextChangingEventArgs(oldText, newText, false);
Callback.OnTextChanging(Widget, args);
if (args.Cancel)
return;

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

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

try
{
TextBox.Text = newText;
}
finally
{
if (endNoGCRegion && GCSettings.LatencyMode == GCLatencyMode.NoGCRegion)
GC.EndNoGCRegion();
}

if (needsTextChanged)
{
Callback.OnTextChanged(Widget, EventArgs.Empty);
}
try
{
endNoGCRegion &= GC.TryStartNoGCRegion(1000000); // is this magic number reasonable??
}
catch
{
// Ignore any exceptions, they can apparently still happen even though we check the LatencyMode above
endNoGCRegion = false;
}

try
{
TextBox.Text = newText;
}
finally
{
if (endNoGCRegion && GCSettings.LatencyMode == GCLatencyMode.NoGCRegion)
GC.EndNoGCRegion();
}

if (value != null && AutoSelectMode == AutoSelectMode.Never && !HasFocus)
{
TextBox.BeginChange();
TextBox.SelectionStart = value.Length;
TextBox.SelectionLength = 0;
TextBox.EndChange();
}

if (needsTextChanged)
{
Callback.OnTextChanged(Widget, EventArgs.Empty);
}
TextBox.EndChange();
}
}

Expand Down
28 changes: 28 additions & 0 deletions test/Eto.Test/UnitTests/Forms/Controls/TextBoxTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,34 @@ namespace Eto.Test.UnitTests.Forms.Controls
public abstract class TextBoxBase<T> : TestBase
where T: TextBox, new()
{
[Test, ManualTest]
public void SettingTextShouldClearUndoBuffer()
{
ManualForm("Try typing and undo/redo, then press the button to reset. After reset, it should not undo to previous values", form =>
{
var textBox = new T();
textBox.Text = "Hello";
textBox.SelectAll();

var button = new Button { Text = "Click Me" };
button.Click += (sender, e) =>
{
textBox.Text = "Thanks, now try to undo";
textBox.Focus();
};

return new TableLayout
{
Spacing = new Size(5, 5),
Padding = 10,
Rows = {
textBox,
button
}
};
});
}

[Test, ManualTest]
public void CaretIndexShouldStartInInitialPosition()
{
Expand Down

0 comments on commit 24b8fa6

Please sign in to comment.