Search code examples
c#wpfxamlmvvmsetvalue

WPF mvvm binding, get/set value: issue with preventing update value


I'm working in a WPF mvvm environment.

I have some binded vars and data from cs file to xaml.

One is different from others: it is the index of the selected tab in my tabsCollection. When the user has more than one tab opened and has got mods to save, I show him a dialog. If he cliks "ok", he proceed with the change of the tab, if he clicks "cancel", the tab must remain the same.

this is my code:

private int p_SelectedDocumentIndex;
public int SelectedDocumentIndex{ get { return p_SelectedDocumentIndex; }
    set {
        if (tabsCollection.Count() > 1 && CanSave() == true)
        {
            if (dm.ShowMessage1(ServiceContainer.GetService<DevExpress.Mvvm.IDialogService>("confirmYesNo")))
            {
                p_SelectedDocumentIndex = value;
                base.RaisePropertiesChanged("SelectedDocumentIndex");
            }
            //else {
            //    CODE FOR NOT CHANGE THE VALUE 
            //}
        }
        else {
            p_SelectedDocumentIndex = value;
            base.RaisePropertiesChanged("SelectedDocumentIndex");
        }
    }
 }

So, the question is: how can I not apply the change in the "set" section? (like an undo, I think)

This is simpliest way to do it, but, if this approach is incorrect, how can I do?

Previous failed attempts:

1)
p_SelectedDocumentIndex = p_SelectedDocumentIndex
base.RaisePropertiesChanged("SelectedDocumentIndex");

2)
base.RaisePropertiesChanged("SelectedDocumentIndex");

3)
nothing in the else branch

Solution

  • I solved it. I've took the solution from here:

    http://blog.alner.net/archive/2010/04/25/cancelling-selection-change-in-a-bound-wpf-combo-box.aspx

        public int SelectedDocumentIndex{ get { return p_SelectedDocumentIndex; }
            set {
                // Store the current value so that we can 
                // change it back if needed.
                var origValue = p_SelectedDocumentIndex;
    
                // If the value hasn't changed, don't do anything.
                if (value == p_SelectedDocumentIndex)
                    return;
    
                // Note that we actually change the value for now.
                // This is necessary because WPF seems to query the 
                //  value after the change. The combo box
                // likes to know that the value did change.
                p_SelectedDocumentIndex = value;
                if (tabsCollection.Count() > 1 && CanSave() == true)
                {
                    if (!dm.ShowMessage1(ServiceContainer.GetService<DevExpress.Mvvm.IDialogService>("confirmYesNo")))
                    {
                        Debug.WriteLine("Selection Cancelled.");
    
                        // change the value back, but do so after the 
                        // UI has finished it's current context operation.
                        Application.Current.Dispatcher.BeginInvoke(
                                new Action(() =>
                                {
                                    Debug.WriteLine("Dispatcher BeginInvoke " + "Setting CurrentPersonCancellable.");
    
                                    // Do this against the underlying value so 
                                    //  that we don't invoke the cancellation question again.
                                    p_SelectedDocumentIndex = origValue;
                                    DocumentPanel p = tabsCollection.ElementAt(p_SelectedDocumentIndex);
                                    p.IsActive = true;
                                    base.RaisePropertiesChanged("SelectedDocumentIndex");
                                }),
                                System.Windows.Threading.DispatcherPriority.ContextIdle,
                                null
                            );
    
                        // Exit early. 
                        return;
                    }
                }
                // Normal path. Selection applied. 
                // Raise PropertyChanged on the field.
                Debug.WriteLine("Selection applied.");
                base.RaisePropertiesChanged("SelectedDocumentIndex");
            }
        }