Why isn't a property in my ViewModel updated when DataGrid changes?

后端 未结 1 1616
轮回少年
轮回少年 2021-01-27 08:41

I\'m trying to create a UserControl, that will let me edit a Dictionary of type Dictionary in a grid (just editing entries so far, not adding o

1条回答
  •  梦毁少年i
    2021-01-27 09:17

    There's actually two issues here: your DictionaryEntry class should implement INotifyPropertyChanged to work correctly with the binding engine, and secondarily it should implement IEditableObject because you want to edit items in a data grid and avoid 'random results'. So your class should look something like this...

    public class DictionaryEntry : INotifyPropertyChanged, IEditableObject
    {
        private string _k;
        [Description("The key")]
        public string K
        {
            [DebuggerStepThrough]
            get { return _k; }
            [DebuggerStepThrough]
            set
            {
                if (value != _k)
                {
                    _k = value;
                    OnPropertyChanged("K");
                }
            }
        }
        private string _v;
        [Description("The value")]
        public string V
        {
            [DebuggerStepThrough]
            get { return _v; }
            [DebuggerStepThrough]
            set
            {
                if (value != _v)
                {
                    _v = value;
                    OnPropertyChanged("V");
                }
            }
        }
        #region INotifyPropertyChanged Implementation
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string name)
        {
            var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
        #endregion
        #region IEditableObject
        public void BeginEdit()
        {
            // implementation goes here
        }
        public void CancelEdit()
        {
            // implementation goes here
        }
        public void EndEdit()
        {
            // implementation goes here
        }
        #endregion
    }
    

    In your ViewModel (or code behind) you would instantiate it like this...

        public ObservableCollection MyItems { get; set; } 
        public ViewModel()
        {
            MyItems = new ObservableCollection();
            MyItems.Add(new DictionaryEntry{K="string1", V="value1"});
            MyItems.Add(new DictionaryEntry { K = "color", V = "red" });
        }
    

    ...which is pretty close to what you have. And the Xaml would look like this...

        
        
    

    Those things will bring about the behaviour you are after. I.e., edits will be sticky.

    On the IEditableObject interface vis-à-vis DataGrids, it's a known 'gotcha' and there's a description of it here... http://blogs.msdn.com/b/vinsibal/archive/2009/04/07/5-random-gotchas-with-the-wpf-datagrid.aspx

    which says...

    If you are not familiar with IEditableObject, see this MSDN article which has a good explanation and code sample. The DataGrid has baked in functionality for transactional editing via the IEditableObject interface. When you begin editing a cell, the DataGrid gets into cell editing mode as well as row editing mode. What this means is that you can cancel/commit cells as well as cancel/commit rows. For example, I edit cell 0 and press tab to the next cell. Cell 0 is committed when pressing tab. I start typing in cell 1 and realize I want to cancel the operation. I press ‘Esc’ which reverts cell 1. I now realize I want to cancel the whole operation so I press ‘Esc’ again and now cell 0 is reverted back to its original value.

    0 讨论(0)
提交回复
热议问题