locked
Implementing "IsDirty" for XAML TextBox

    Question

  • I am looking for pointers to examples of an "IsDirty" implementing for XAML TextBox controls.  The behavior I am looking for is that as soon as a user modifies the value of a TextBox (by typing a character, for example), I want the data entry to be "flagged" as dirty so that I can do things like enable the Save button (via data binding), for example.  In addition, I want the user to be informed of unsaved changes if they try to navigate away from the data entry view.  The user should be able to return to the data entry view or choose to ignore the changes and continue on to wherever they are navigating to.

    I have an MVVM implementation that I have working but it seems awkward.  The key to my approach is to use the TextChanged event to check for the "IsDirty" condition.  You may be tempted to implement this by simply setting the "IsDirty" flag to true in this event but this won't work since this event fires when data binding occurs during the initialization of the TextBox fields as well as when the user modifies the value of a field so the logic for that handler has to take that into account and work in both cases.  If you were to simply set "IsDirty" to true, the data entry process would be initialized as "dirty" since the TextChanged handler gets called to initialize the contents of the field.

    Something else that makes implementing "IsDirty" in the TextChanged handler awkward is that even with TwoWay binding, the model is not updated with the user's modification before the handler is called so you are forced to use the TextBox.Text property to get the current value of the user input.

    So my approach was do a "BeginEdit", "EndEdit", and "UndoChanges" style of logic where BeginEdit, EndEdit and UndoChanges all set IsDirty to false and I manually check the current contents of TextBox.Text against its original value (that was saved using a deep copy of the Model during the BeginEdit) in the TextChanged handler.  This way, during the initialization of the TextBox the TextChanged handler won't see any differences since they will be equal at that point, but once the user modifies the input field the handler will once again fire and then when I test TextBox.Text againt the original I will set the IsDirty flag.

    This seem like waaaay too much work and that is usually an indication you are going about things the wrong way.  Any one have pointers to a better approach for the TextBox specifically.  I would not take this approach with other data entry controls but given the way the TextBox is implemented I am specifically asking about solutions for it.

    Seems to me that life would have been so much easier if the TextBox had a TextChanged AND a TextInitialized event (or some way for me to tell that the TextBox was being initialized in the TextChanged handler) and then the TextChanged implementation could have simply been { model.IsDirty = true;}


    -Russ

    Tuesday, December 30, 2014 3:18 AM

Answers

  • I believe the best approach would be to add the IsDirty flag to the ViewModel of the page. So when the bound data is modified IsDirty gets set to true. I guess your ViewModel implements INotifyPropertyChanged so basically whenever you would fire the PropertyChanged Event you would set IsDirty to true. Whenever the data gets saved or reset you would reset it to false.

    All your UI logic would work based on the ViewModel (e.g. binding Button states to IsDirty).

    The general idea behind using a ViewModel in addition to a model (otherwise you could simply bind the Model-objects to the UI) is to have all necessary logic for the UI behavior and state be encapsulated in the ViewModel.

    Hope that helps.

    Tuesday, December 30, 2014 8:15 AM