I want to allow the user to input only text that is validated by the TextBox binding validation rules. I figured out a way of doing that:
public static void PreviewTextChanged(
object sender,
PreviewTextChangedEventArgs e)
{
var textBox = e.Source as TextBox;
var bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty);
if (!ReferenceEquals(null, bindingExpression))
{
// save original parameters for possible restoration
var originalSelectionStart = textBox.SelectionStart;
var originalSelectionLength = textBox.SelectionLength;
var originalText = textBox.Text;
// check validation
textBox.Text = e.Text;
if (!bindingExpression.ValidateWithoutUpdate())
{
// restore original values
textBox.Text = originalText;
bindingExpression.UpdateSource();
textBox.SelectionStart = originalSelectionStart;
textBox.SelectionLength = originalSelectionLength;
}
else
{
// correct the selection
var selectionStart = originalSelectionStart +
originalSelectionLength +
e.Text.Length -
originalText.Length;
textBox.SelectionStart = Math.Max(selectionStart, 0);
textBox.SelectionLength = 0;
}
e.Handled = true;
}
}
The code above works. But it would be much simpler, and less bug-prone, if I could find a way to check if the new value is valid without updating the binding target. Is there one?