Reputation: 146
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
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