TSM
TSM

Reputation: 582

TextBox TextChanged Event Problems

I'm using a basic TextBox that is bound to an object. Basically, what I want to do is call a method every time the text in the box is edited and the user de-selects the box or when the underlying bound data is edited. What I am using right now is the TextChanged event, but this has a few problems:

  1. It is called when the TextBox is first created, and I don't want this.

  2. It is called every time a new character is added, and I only want it called when the underlying bound data is changed (which seems to be whenever focus shifts from the box).

How can I accomplish this?

EDIT: I've tried several other TextBox properties like Get/LostFocus but they never seem to fire.

Also, I don't want to put this method call in the Setter of the Property, because the underlying data is something that is logically separate from the UI of this project and I don't want any method calls that relate to doing computations for the UI.

Upvotes: 1

Views: 6411

Answers (5)

Ganesh
Ganesh

Reputation: 131

I am not sure what you are finally trying to achieve but I am going to take a guess at this. If you are following an MVVM pattern then, then it seems like you can achieve what you want by using the updateSourceTrigger property of the binding. If you are not using MVVM then you might what to take a look at using MVVM

Upvotes: -1

Bill Zhang
Bill Zhang

Reputation: 1939

As jods says, the best way to bind your TextBox's Text to ViewModel's property. The Code are:

View:

<TextBox x:Name="TextBox1" Text="{Binding Path=Text1,Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>

ViewModel:

    public string Text1
    {
        get { return _text1; }
        set
        {
            _text1 = value;
            RaisePropertyChanged("Text1");
        }
    }

View code behind:

    private void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Text1")
        {
            //Call UI related method...
        }
    }

In this way, it satisfy your two conditions: 1. Every time when you edit TextBox and lose the focus, Setter of Text1 will be called and ViewModel will raise PropertyChanged event. 2. When underlying Text1 is changed. Text1 will also raise the event so View can know it.

Also it can avoid your two concerns: 1. In the first time binding, only getter of Text1 is called. No event is raised. 2. Setter of Text1 is only called after TextBox is lost focus.

Upvotes: 1

jods
jods

Reputation: 4591

Best design is to listen for changes in the underlying bound property. You can do that without changing the setter if you use a DependencyProperty or if your object implements INotifyPropertyChanged.

When the underlying property changes (LostFocus by default, or each char at a time) is a binding option.

If you don't want to follow my advice of listenning for changes in your (view-)model, you could subscribe to GotFocus and LostFocus events. Save the current value when you get focus, compare with current value when you lose it. If it's different -> do what it is you want to do.

Upvotes: 0

user2517337
user2517337

Reputation: 11

The event LostFocus fires when the focus is shifted from the current element. I tried it and its working fine.

Upvotes: 1

Wojciech Kulik
Wojciech Kulik

Reputation: 8500

every time the text in the box is edited and the user de-selects the box

Hmmm AFAIK it's a standard behaviour of TextBox if you bind text like that: Text={Binding Property}

when the underlying bound data is edited

You can provide this functionality inside setter of your property.

Upvotes: 0

Related Questions