Unable to use Undo in TextChanged
c#, undo, wpf
Solution
Instead of using Undo and TextChanged, you should use the `PreviewTextInput` and `DataObject.Pasting` events. In the `PreviewTextInput` event handler, set `e.Handled` to true if the typed text is an invalid character. In the `Pasting` event handler, call `e.CancelCommand()` if the pasted text is invalid.
Here is an example for a text box that accepts only the digits 0 and 1:
XAML:
<Window x:Class="BinaryTextBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="133" Width="329">
<StackPanel>
<TextBox x:Name="txtBinary" Width="100" Height="24"
PreviewTextInput="txtBinary_PreviewTextInput"
DataObject.Pasting="txtBinary_Pasting"/>
</StackPanel>
</Window>
Code behind:
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Input;
namespace BinaryTextBox
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void txtBinary_PreviewTextInput(object sender,
TextCompositionEventArgs e)
{
e.Handled = e.Text != "0" && e.Text != "1";
}
private void txtBinary_Pasting(object sender, DataObjectPastingEventArgs e)
{
if (!Regex.IsMatch(e.DataObject.GetData(typeof(string)).ToString(), "^[01]+$"))
{
e.CancelCommand();
}
}
}
}
Problem
When using textbox.Undo(); I get the following error: Cannot Undo or Redo while undo unit is open. Now I understand why this is the case (because it is an active undoable event) but through what event can I perform validation on a text box and undo the change if the user has typed an invalid character?