WPF ComboBox SelectedItem - change to previous value

前端 未结 4 1079
Happy的楠姐
Happy的楠姐 2020-12-30 00:13

I have a ComboBox that has the SelectedItem bound to the ViewModel.



        
4条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-30 01:08

    Thanks for this question and answers. The Dispatcher.BeginInvoke helped me and was part of my final solution, but the above solution didn't quite work in my WPF 4 app.

    I put together a small sample to figure out why. I had to add code that actually changed the underlying member variable's value temporarily so that when WPF re-queried the getter, it would see that the value chaned. Otherwise, the UI didn't properly reflect the cancellation and the BeginInvoke() call did not do anything.

    Here's a my blog post with my sample showing a non-working and a working implementation.

    My setter ended up looking like this:

        private Person _CurrentPersonCancellable;
        public Person CurrentPersonCancellable
        {
            get
            {
                Debug.WriteLine("Getting CurrentPersonCancellable.");
                return _CurrentPersonCancellable;
            }
            set
            {
                // Store the current value so that we can 
                // change it back if needed.
                var origValue = _CurrentPersonCancellable;
    
                // If the value hasn't changed, don't do anything.
                if (value == _CurrentPersonCancellable)
                    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.
                _CurrentPersonCancellable = value;
    
                if (
                    MessageBox.Show(
                        "Allow change of selected item?", 
                        "Continue", 
                        MessageBoxButton.YesNo
                    ) != MessageBoxResult.Yes
                )
                {
                    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.
                                _CurrentPersonCancellable = origValue;
                                OnPropertyChanged("CurrentPersonCancellable");
                            }),
                            DispatcherPriority.ContextIdle,
                            null
                        );
    
                    // Exit early. 
                    return;
                }
    
                // Normal path. Selection applied. 
                // Raise PropertyChanged on the field.
                Debug.WriteLine("Selection applied.");
                OnPropertyChanged("CurrentPersonCancellable");
            }
        }
    

提交回复
热议问题