gpt4 book ai didi

c# - WPF INotifyPropertyChanged 两种方式绑定(bind)奇怪的 Action

转载 作者:行者123 更新时间:2023-12-03 10:56:36 24 4
gpt4 key购买 nike

我实现了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"); }
}
}

View 模型由模型和用于更改模型属性的命令组成。
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";
}
}

然后将 VM 绑定(bind)到 View 。
<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不会更新为新值。
但是,如果我实现 INotifyPropertyChanged喜欢 this指令,绑定(bind)工作。
实现 2
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 是您的 OnPropertyChanged 的字符串参数吗?方法需要是正在更改的确切属性名称。对于您的两个示例,"model_changed"应改为"Model""name_changed"应阅读 "Name" .这里有两种很好的技术来减轻输入文字字符串名称时潜在的人为错误:

1. 使用CallerMemberName属性

如果您被允许并有权访问 System.Runtime.CompilerServices命名空间,您可以编写您的基类以使属性名称自 Action 为 OnPropertyChanged 的字符串参数传递。方法:

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()在您的属性(property)的 setter/getter 中。

2. 使用nameof关键字

或者,您可以简单地将文字类型的属性名称替换为 nameof(<InsertPropertyNameHere>)这将返回名称而不会有任何错误输入的风险,例如以下示例:
public class Model : Notifier, IDataErrorInfo
{
private string name;

public string Name
{
get { return name; }
set { name = value; OnPropertyChanged(nameof(Name)); }
}
}

关于c# - WPF INotifyPropertyChanged 两种方式绑定(bind)奇怪的 Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55390095/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com