Prodromos
Prodromos

Reputation: 146

WPF TextBox detect if text overflowed

I try to detect if the TextBox is overflowed. I use code like this:

textbox.UpdateLayout;
textbox.ExtentWidth > textbox.ViewportWidth

I use it in the following event handlers:

Loaded
TextChanged
TargetChanged 

(binding is using NotifyOnTargetUpdated = True and UpdateSourceTrigger=PropertyChanged, IsAsync = False)

This works fine. Except in one case. If the TextBox starts overflowed it is not detected. If the Textbox.Text uses Binding The ExtentWidth is zero, even in the TargetChanged event handler. If it is some plain Text like "123", it gets the correct value. What do I miss?

Thanks.

Upvotes: 0

Views: 856

Answers (1)

BionicCode
BionicCode

Reputation: 28968

It should work. TextBoxBase.TextChanged sometimes behaves different than expected. Some internal operations are executed after the text has changed e.g., caret positioning or measuring. Measuring will affect the TextBoxBase.ExtendWidth and TextBoxBase.ViewportWidth.

The solution is to defer all custom operations, that are meant to be triggered by the TextChanged event. Custom code should be executed after all internal operations of the TextBox are completed.
You can defer code execution by enqueuing it to the dispatcher's queue asynchronously. Asynchronous dispatcher operations are executed after all current dispatcher operations are completed:

private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
{
  this.Dispatcher.InvokeAsync(
    () =>
    {
      var textBox = sender as TextBox;
      bool textBoxHasOverflowContent = textBox.ExtentWidth > textBox.ViewportWidth;
    });
}

Upvotes: 1

Related Questions