Well, if you look at it closely, it’s not really the TextEdit itself that fires twice, but it delegates the editing to a Windows system TextBox, so it fires when that happens – and later again, when it really loses focus (see explanation and a workaround here).
I always use an _autoChange flag in my windows to stop events from firing when I set things by code, plus I found out I could catch all the RoutedEvents that do not come from a TextBox type. That helped reduce event calls.
Second problem I came across was: what if I had to use an Alert or MessageBox during handing of the event, say to inform a user of a problem with the data entered? Guess, you end up with an infinite loop of that event firing and firing… But I managed to stop that by using my internal OldValue / NewValue set, that usually goes to the EditorValueChanged event to inform any listerners about what was the change. By comparing for equality I could get out of that loop – no need to call any *Changed events, when the figures are equal anyway. This allows me to even use a MessageBox during the handling of that EditorValueChanged event: the TextEdit will lose focus, but it will not re-fire the event. Just once, when it’s first losing focus.
private void Editor_LostFocus(object sender, RoutedEventArgs e) { if (_autoChange || e.OriginalSource.GetType() != typeof(System.Windows.Controls.TextBox)) return; var te = sender as TextEdit; if (te == null) return; _values.OldValue = EditorValue; _values.NewValue = new ValueBase(Convert.ToDecimal(te.EditValue.ToString())); if (_values.OldValue.ValueDecimal == _values.NewValue.ValueDecimal) return; _values.EditValue = _values.NewValue; var eva = new UniversalInplaceEditorChangedArgs { ValueSet = _values }; _autoChange = true; if (EditorValueChanged != null) EditorValueChanged(this, eva); _autoChange = false; }