5

I am having trouble with textbox.textchanged event. my textboxes are data-bound and when the page is loaded, textchanged event triggers. How do I prevent it from happening and only trigger when the user makes any sort of changes?

H.B.
  • 166,899
  • 29
  • 327
  • 400
will0809
  • 237
  • 1
  • 5
  • 16
  • May I ask why this initial event call is a problem to begin with? Maybe we can solve the problem behind the problem – Amenti Nov 02 '11 at 06:46
  • hi Amenti. I have a navigation page with a save and cancel button. the page with load with a bunch of textboxes initially filled in with a couple of default values. I need to restrict the ability for the user to navigate out of that page before pressing either the save and cancel button. – will0809 Nov 02 '11 at 07:23
  • i could simulate the cancel button press with something like this: `someButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));` but it didn't work. I put this after InitializeComponent(). Am I doing it wrong? – will0809 Nov 02 '11 at 07:49

4 Answers4

11

Inside textchanged event handlers you can verify if window (or usercontrol, or whatever) is loaded:

if (this.IsLoaded)
{
   //your logic here
}

This way you can skip the first firing of TextChanged events, when the window is not loaded yet.

icebat
  • 4,696
  • 4
  • 22
  • 36
  • Hi icebat. i've tried this but the first thing it hits after everything is initialized and loaded, is the textchanged event. So it fired anyway. – will0809 Nov 02 '11 at 07:44
  • can't you have a default value you can check just the first time and then change it? – MaRuf Nov 02 '11 at 07:55
  • @will0809, thats strange. How do you set default values? Are thet databound or set in code? – icebat Nov 02 '11 at 08:20
  • @icebat, they are databound. this is really weird because it works for the other form i implemented. the xaml: `` – will0809 Nov 03 '11 at 01:12
  • in the codebehind I have this: ` void UserConfiguration_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { m_IsDirty = true; RefreshStatusMessage(); } ` – will0809 Nov 03 '11 at 01:16
  • as well as this: ` User user = wcf.GetUser(selectedUser.Id); user.PropertyChanged += UserConfiguration_PropertyChanged; ` – will0809 Nov 03 '11 at 01:17
  • It seems the problem is not in TextBox, but in PropertyChanged event firing too early. It may be a good idea to move 'user.PropertyChanged += UserConfiguration_PropertyChanged' to Loaded event handler, as AkselK showed in his answer. You have to set default values _before_ you hook PropertyChanged event. – icebat Nov 03 '11 at 06:33
3

The problem is that whenever the text is set, TextChanged triggers. That is just the way WPF works. You can "fix" this by setting events in codebehind, by subscribing to the Loaded event of the Window/Usercontrol. The Loaded event fires after every child, and their childs, have finished loading, and is ready to be displayed.

<UserControl ---- Loaded="UserControl_Loaded">    
-
public void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    _txtBox.TextChanged += txt_changed;
}

public void txt_changed(object sender, RoutedEventArgs e)
{
   (...)
}
AkselK
  • 2,563
  • 21
  • 39
  • i think the reason this doesn't work is that my textboxes are databound, and my default values are loaded into the textboxes after they have finished loading, which causes the textchanged event to fire. – will0809 Nov 03 '11 at 01:33
1

I had the same problem and ended up with a work around.

On the window I added a variable for window loaded and I set this at the end of the Window_Loaded event to true.

On the TextChanged events check if your variable is true.

GuestTP
  • 11
  • 1
1

Well, from your comment I gather that you want the user to make changes which are only propagated to the underlying data when he explicitly saves or closes the form.

You could use the UpdateSourceTrigger "Explicit" here.

<TextBox Text={Binding MyData, UpdateSourceTrigger=Explicit}/>

So your changes are only propagated by explicitly calling UpdateSource on your bindings when your user hits the save button.

If you use MVVM you can also implement the same logic codewise into the ViewModels.

Amenti
  • 1,511
  • 1
  • 13
  • 29