guest
guest

Reputation: 265

determine a textbox's previous value in its lost focused event? WPF

I have a textbox and have an onlostfocus event on it.

Inside the lostfocus method, is there a way I can determine if the user has actually changed the value in it? i.e how do i get hold of any previous value in it?

Thanks

Upvotes: 4

Views: 7939

Answers (5)

Masaki Ohashi
Masaki Ohashi

Reputation: 491

When TextBox lost it's focus, then Binding is going to update data source. So check the source before the update, and you can get the previous value.

Example:

void TextBox_OnLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs args) {
    var textbox = sender as TextBox;
    var bx = textbox.GetBindingExpression(TextBox.TextProperty);
    var item = bx.ResolvedSource as MyDataItem; // source object
    var path = bx.ResolvedSourcePropertyName; // source property
    var previousValue = item.MyProperty;
    bool dirty = bx.IsDirty; // if true, update fires
}

Note: If user input the same value as the previous, it will also be marked as "dirty".

https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-control-when-the-textbox-text-updates-the-source?view=netframeworkdesktop-4.8

Upvotes: 0

Matthew
Matthew

Reputation: 2829

What comes to mind for me is a two stage approach. Handle the TextChanged event on the textbox and flag it. Then when the textbox OnLostFocus occurs you can simply check your flag to see if the text has been changed.

Here is a code snippet on how you could handle the tracking.

public class MyView
{
    private bool _textChanged = false;
    private String _oldValue = String.Empty;

    TextChanged( ... )
    {
        // The user modifed the text, set our flag
        _textChanged = true;        
    } 

    OnLostFocus( ... )
    {
        // Has the text changed?
        if( _textChanged )
        {
            // Do work with _oldValue and the 
            // current value of the textbox          

            // Finished work save the new value as old
            _oldValue = myTextBox.Text;

            // Reset changed flag
            _textChanged = false;
        }              
    }
}

Upvotes: 1

Simon D.
Simon D.

Reputation: 4481

Another way to solve this by databinding: Bind the TextBox.Text to the property, that holds the inital value, but use a binding with UpdateSourceTrigger=Explicit Then, when the textbox loses focus, you can check the binding if source and target values differ, using this code snippet and evaluating the resulting BindingExpression: BindingExpression be = tb.GetBindingExpression(TextBox.TextProperty); Some more code can be found here: http://bea.stollnitz.com/blog/?p=41

Upvotes: 0

Robert Rossney
Robert Rossney

Reputation: 96702

As with just about everything else in WPF, this is easier if you use data binding.

Bind the text box to a class property. By default, bindings update the source when the bound control loses focus, so you don't have to muck around with the LostFocus event. You then have access to both the new value and the value that the user entered in the property setter.

In the XAML it looks like this:

<TextBox Text="{Binding MyProperty, Mode=TwoWay}"/>

In the class it looks like this:

private string _MyProperty;

public string MyProperty
{
   get { return _MyProperty; }
   set
   {
      // at this point, value contains what the user just typed, and 
      // _MyProperty contains the property's previous value.
      if (value != _MyProperty)
      {
         _MyProperty = value;
         // assuming you've implemented INotifyPropertyChanged in the usual way...
         OnPropertyChanged("MyProperty"); 
      }
   }

Upvotes: 4

Kendrick
Kendrick

Reputation: 3787

Store the original value somewhere. You could write a common component to store the value when it gets focus and compare the value when it loses focus. I've done this in ASP.NET and it works quite well.

Upvotes: 0

Related Questions