Ioannis Panagopoulos blog

Tutorials on HTML5, Javascript, WinRT and .NET

What is the sequence of events/method calls in a WPF Textbox for the Text Property?

by Ioannis Panagopoulos

What is the sequence of events/method calls in a WPF Textbox for the Text Property?

The moment you start implementing an enterprise application, you realize that you need to take full control of the Textbox control. So you inherit from it, usually creating MyTextbox or something like this. And now there is a whole bunch of events/methods that you can override in order to modify/control its Text property.

In this post, I will use a simple application (source at the end of the post) where I establish the sequence of occurrence of the following events/methods:

  • Converter Methods (Convert/ConvertBack) of a converter attached to the binding of the Text property.
  • PropertyChanged event of the control
  • DependencyPropertyChanged event of the Text property
  • CoerceValue event of the Text property
  • TextChanged event of the Control
  • GotFocus/LostFocus event of the control
  • TextInput event of the control

I will display the sequence of those events using the following figure as the basis:

This figure says that the Textbox and its Text property can be set either by Keyboard Input (when the user types something in the Textbox) or by Code Input (assigning the Text property of the control to a value). Additionally the Text property can either be visualized in the Textbox (Visual Output) or retrieved in code (Code Output).

We create a new class named TextBoxText1 which inherits from Textbox:

public class TextBoxText1 : TextBox

{

In the class constructor we override the PropertyChanged and CoerceValue of the Text property and define our own:

static TextBoxText1()

{

    FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();

    metadata.PropertyChangedCallback = OnTextPropertyChanged;

    metadata.CoerceValueCallback = OnCoerceTextProperty;

    TextProperty.OverrideMetadata(typeof(TextBoxText1), metadata);

}


 

And the two methods:

public static void OnTextPropertyChanged(DependencyObject sender,DependencyPropertyChangedEventArgs args)

{

    (…)

}

 

public static object OnCoerceTextProperty(DependencyObject sender,object value)

{

    return value.ToString()+"(coer)";

}


 

The first is called whenever the Text property is changed and the second is called just before a new value is assigned to the Text property.

We press the key “A” in the Textbox. In this case the following applies (follow the route from “Keyboard Input”):

When we set the value of the Text property from code the following applies (follow the rout from “Code Input”):

Now we override the following events (those are Textbox events):

protected override void OnTextChanged(TextChangedEventArgs e)

{

    (Code 1)

    base.OnTextChanged(e);

    (Code 2)

}

 

protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)

{

    (Code 1)

    base.OnPropertyChanged(e);

    (Code 2)

}


 

And we also listen to the TextChanged event from the code that uses the control:

void TextBox1_TextChanged(object sender, TextChangedEventArgs e)

{

    Code

}


 

We press the key “A” in the Textbox. In this case the following applies (follow the route from “Keyboard Input”):

Some notes about those:

  • If we comment out the base.OnTextChaged method call then the Textbox1_TextChanged will not be called
  • If we comment out the base.OnPropertyChanged event the Textbox does not work well.

When we set the value of the Text property from code the following applies (follow the rout from “Code Input”):

We move even further and now also override:

protected override void OnTextInput(TextCompositionEventArgs e)

{

 

    (Code 1)

    base.OnTextInput(e);

    (Code 2)

}

 

protected override void OnLostFocus(RoutedEventArgs e)

{

    (Code 1)

    base.OnLostFocus(e);

    (Code 2)

}


 

We also listen to the Lost Focus event from our client code:

void TextBox1_LostFocus(object sender, RoutedEventArgs e)

{

    (…)

}


 

We press the key “A” in the Textbox. In this case the following applies (follow the route from “Keyboard Input”):

Some notes about those:
* If we comment out the base.OnTextInput method call then the whole sequence is suppressed and nothing is displayed on the Textbox.
* If we comment out the base.OnLostFocus event the TextBox1_LostFocus will never be called.

We take now this another step further by adding DataBinding to the Text property of the control. The databound value is the string “TestValue”.

We press the key “A” in the Textbox. In this case the same events are fired as in the previous case. The only thing to note is that TestValue will be set (the setter will be called) just after OnLostFocus(Code1) and before TextBox1_LostFocus. If we comment out base.OnLostFocus , the setter is never called (this applies only if we set that the UpdateSourceTrigger to LostFocus – the default).

An interesting thing to keep in mind is that although the Text property has the coerced value “A(coer)” the bound value TestValue always has the non-coerced value “A”.

Of course setting the Text property by code, will not affect the value of the TestValue. If we set the TestValue by code the sequence of events is the same as setting the Text Property.

The interesting thing happens when we add the following converter:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

{

    return value.ToString()+"(conv)";

}

 

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

{

    (…)

    return value.ToString()+”(back)”;

}


 

Suppose now that we enter the character “A” in the Textbox. Converter magic happens when the Textbox looses the focus.

1. Converter’s method ConvertBack is called with value “A”.
2. TestValue Setter is called. The value returned from ConvertBack is set to TestValue “A(back)”.
3. Converter’s method Convert is called to retrieve the value “A(back)” and change it to “A(back)(conv)”.
4. Sequence of events like setting the Text property.

If we set the TestValue in code, the value is set in the Setter, the Converter’s Convert method is called and the the sequence is the same as setting the Text property.

And this completes the Textbox event GPS!

kick it on DotNetKicks.com  Shout it

TextBoxTests.zip (53,56 kb)

blog comments powered by Disqus
hire me