WPF MVVM - How to detect if a View is “Dirty”

前端 未结 2 1333
不思量自难忘°
不思量自难忘° 2020-12-12 19:56

I currently have a requirement to notify my application user if any fields have been changed/updated on a View.

For example, if the user changes a date field on the

2条回答
  •  伪装坚强ぢ
    2020-12-12 20:26

    In MVVM a View is binded to a View-Model which in turn is binded to a Model.

    The view can not be dirty, since it's changes are reflected immediately to the View-Model.

    If you want changes to be applied to Model only on "OK" or "Accept",
    bind View to a View-Model that doesn't apply changes to Model,
    until an ApplyCommand or AcceptCommand (that you define and implement) is executed.

    (The commands that the View is binded to are implemented by the View-Model.)

    Example - VM:

    public class MyVM : INotifyPropertyChanged
    {
        public string MyText
        {
            get
            {
                return _MyText;
            }
            set
            {
                if (value == _MyText)
                    return;
    
                _MyText = value;
                NotifyPropertyChanged("MyText");
            }
        }
        private string _MyText;
    
        public string MyTextTemp
        {
            get
            {
                return _MyTextTemp;
            }
            set
            {
                if (value == _MyTextTemp)
                    return;
    
                _MyTextTemp = value;
                NotifyPropertyChanged("MyTextTemp");
                NotifyPropertyChanged("IsTextDirty");
            }
        }
        private string _MyTextTemp;
    
        public bool IsTextDirty
        {
            get
            {
                return MyText != MyTextTemp;
            }
        }
    
        public bool IsMyTextBeingEdited
        {
            get
            {
                return _IsMyTextBeingEdited;
            }
            set
            {
                if (value == _IsMyTextBeingEdited)
                    return;
    
                _IsMyTextBeingEdited = value;
    
                if (!value)
                {
                    MyText = MyTextTemp;
                }
    
                NotifyPropertyChanged("IsMyTextBeingEdited");
            }
        }
        private bool _IsMyTextBeingEdited;
    
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    Example - View:

        

    Example - view - code behind:

        public MainWindow()
        {
            InitializeComponent();
    
            SetBinding(IsTextBoxFocusedProperty,
                new Binding
                {
                    Path = new PropertyPath("IsMyTextBeingEdited"),
                    Mode = BindingMode.OneWayToSource,
                });
        }
    
        private void TextBox_LostFocus(object sender, RoutedEventArgs e)
        {
            IsTextBoxFocused = false;
        }
    
        private void TextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            IsTextBoxFocused = true;
        }
    
        #region IsTextBoxFocused
    
        /// 
        /// Gets or Sets IsTextBoxFocused
        /// 
        public bool IsTextBoxFocused
        {
            get
            {
                return (bool)this.GetValue(IsTextBoxFocusedProperty);
            }
            set
            {
                this.SetValue(IsTextBoxFocusedProperty, value);
            }
        }
    
        /// 
        /// The backing DependencyProperty behind IsTextBoxFocused
        /// 
        public static readonly DependencyProperty IsTextBoxFocusedProperty = DependencyProperty.Register(
          "IsTextBoxFocused", typeof(bool), typeof(MainWindow), new PropertyMetadata(default(bool)));
    
        #endregion
    

提交回复
热议问题