代码之家  ›  专栏  ›  技术社区  ›  M. Ko

WPF INotifyPropertyChanged双向绑定操作

  •  1
  • M. Ko  · 技术社区  · 5 年前

    INotifyPropertyChanged
    实施1

    public class Notifier : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        public void OnPropertyChanged(string pName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(pName));
        }
    }
    
    public class Model : Notifier, IDataErrorInfo
    {
        private string name;
    
        public string Name
        {
            get { return name; }
            set { name = value; OnPropertyChanged("name_changed"); }
        }
    }
    

    viewmodel由模型和对模型属性进行更改的命令组成。

    public class ViewModel : Notifier
    {
        private Model _model;
    
        public Model Model
        {
            get { return _model; }
            set { _model = value; OnPropertyChanged("model_changed"); }
        }
    
        private ICommand _cmd;
    
        public ICommand Command
        {
            get { return _cmd; }
            set { _cmd = value; }
        }
    
        public void ExecuteCommand(object para)
        {
            Console.WriteLine("Command executed");
            Model.Name = "new name";
        }
    }
    

    <TextBox HorizontalAlignment="Center" VerticalAlignment="Center"  Width="100">
        <TextBox.Text>
            <Binding Path="Model.Name" Mode="TwoWay" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
                <Binding.ValidationRules>
                    <ExceptionValidationRule></ExceptionValidationRule>                
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    

    当执行命令时 TextBox
    但是,如果我实现 InotifyProperty已更改 喜欢 this

    public class Notifier : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected bool SetProperty<T>(ref T field, T newValue, [CallerMemberName]string propertyName = null)
        {
            if (!EqualityComparer<T>.Default.Equals(field, newValue))
            {
                field = newValue;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
                return true;
            }
            return false;
        }
    }
    
    public class Model : Notifier, IDataErrorInfo
    {
        private string name;
    
        public string Name
        {
            get { return name; }
            set { SetProperty(ref name, value); }
        }
    }
    

    第一种方法遗漏了什么?

    1 回复  |  直到 5 年前
        1
  •  0
  •   Hemang A    5 年前

    请像这样添加属性名。

    public class Model : Notifier, IDataErrorInfo
    {
        private string name;
    
        public string Name
        {
            get { return name; }
            set { name = value; OnPropertyChanged("Name"); }
        }
    }
    
        2
  •  3
  •   Paul Karkoska    5 年前

    这是你的字符串参数吗 OnPropertyChanged 方法必须是正在更改的确切属性名。举两个例子, "model_changed" 应改为 "Model" "name_changed" "Name" . 以下是两种很好的技术,可以通过键入文字字符串名称来减轻潜在的人为错误:

    CallerMemberName 属性

    如果您被允许并有权访问 System.Runtime.CompilerServices 命名空间中,可以这样编写基类,使属性名自动作为 方法:

    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    
    public class Notifier : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string pName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(pName));
        }
    }
    

    OnPropertyChanged() 在你的房子里。

    2使用 nameof 关键字

    或者,您可以简单地用 nameof(<InsertPropertyNameHere>) 它将返回名称而不存在任何输入错误的风险,例如:

    public class Model : Notifier, IDataErrorInfo
    {
        private string name;
    
        public string Name
        {
            get { return name; }
            set { name = value; OnPropertyChanged(nameof(Name)); }
        }
    }