How to rollback selected SelectedValue of the comb

2020-07-11 04:39发布

I have something like it will pop to the user for getting confirmation of changes. If he clicks no I am setting the selectedValue in view model to the previous selection. But its not getting displayed correctly in view. Please help.

标签: wpf mvvm
8条回答
太酷不给撩
2楼-- · 2020-07-11 04:58

Here is the general flow that I use:

  1. I just let the change pass through the ViewModel and keep track of whatever's passed in before. (If your business logic requires the selected item to not be in an invalid state, I suggest moving that to the Model side). This approach is also friendly to ListBoxes that are rendered using Radio Buttons as making the SelectedItem setter exit as soon as possible will not prevent radio buttons from being highlighted when a message box pops out.
  2. I immediately call the OnPropertyChanged event regardless of the value passed in.
  3. I put any undo logic in a handler and call that using SynchronizationContext.Post() (BTW: SynchronizationContext.Post also works for Windows Store Apps. So if you have shared ViewModel code, this approach would still work).

    public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        public List<string> Items { get; set; }
    
        private string _selectedItem;
        private string _previouslySelectedItem;
        public string SelectedItem
        {
            get
            {
                return _selectedItem;
            }
            set
            {
                _previouslySelectedItem = _selectedItem;
                _selectedItem = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
                }
                SynchronizationContext.Current.Post(selectionChanged, null);
            }
        }
    
        private void selectionChanged(object state)
        {
            if (SelectedItem != Items[0])
            {
                MessageBox.Show("Cannot select that");
                SelectedItem = Items[0];
            }
        }
    
        public ViewModel()
        {
            Items = new List<string>();
            for (int i = 0; i < 10; ++i)
            {
                Items.Add(string.Format("Item {0}", i));
            }
        }
    }
    
查看更多
劳资没心,怎么记你
3楼-- · 2020-07-11 05:00

Very simple solution for .NET 4.5.1+:

<ComboBox SelectedItem="{Binding SelectedItem, Delay=10}" ItemsSource="{Binding Items}"  />

It's works for me in all cases. Just fire NotifyPropertyChanged without value assignment to rollback.

查看更多
登录 后发表回答