C# 以编程方式更改属性设置器逻辑
我需要添加属性设置程序的逻辑 例如,我有一个名为“CurrentTab”的属性: 这一切都很好,也很有效,但我希望能够这样定义:C# 以编程方式更改属性设置器逻辑,c#,.net,reflection,properties,C#,.net,Reflection,Properties,我需要添加属性设置程序的逻辑 例如,我有一个名为“CurrentTab”的属性: 这一切都很好,也很有效,但我希望能够这样定义: public WorkspaceViewModel CurrentTab { get; set; } [NotifyPropertyChanged] public WorkspaceViewModel CurrentTab { get; set; } 因此,在setter运行后,系统会自动为属性名执行OnPropertyChanged()函数,而无需我添加任何特定
public WorkspaceViewModel CurrentTab { get; set; }
[NotifyPropertyChanged]
public WorkspaceViewModel CurrentTab { get; set; }
因此,在setter运行后,系统会自动为属性名执行OnPropertyChanged()函数,而无需我添加任何特定代码。
如何确定哪些属性需要遵循这个逻辑是没有问题的,我只需要找到一种方法来真正做到这一点
我想让这更简单,因为我会有很多这样的属性,我想保持它干净
有办法吗?
非常感谢您的帮助 看一看:。有一个用于INotifyPropertyChange的外接程序:
它是在构建解决方案时操作IL代码
只需将属性添加到视图模型:
[ImplementPropertyChanged]
public class Person
{
public string GivenNames { get; set; }
public string FamilyName { get; set; }
public string FullName
{
get
{
return string.Format("{0} {1}", GivenNames, FamilyName);
}
}
}
编译代码时:
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string givenNames;
public string GivenNames
{
get { return givenNames; }
set
{
if (value != givenNames)
{
givenNames = value;
OnPropertyChanged("GivenNames");
OnPropertyChanged("FullName");
}
}
}
string familyName;
public string FamilyName
{
get { return familyName; }
set
{
if (value != familyName)
{
familyName = value;
OnPropertyChanged("FamilyName");
OnPropertyChanged("FullName");
}
}
}
public string FullName
{
get
{
return string.Format("{0} {1}", GivenNames, FamilyName);
}
}
public virtual void OnPropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
这可以通过以下方法实现: 在计算中,面向方面编程(AOP)是一种编程方法 通过允许分离来增加模块化的范例 跨领域关注的问题。AOP是面向方面的基础 软件开发 您可以使用名为
InstanceLevelAspect
的方面来实现这一点:
/// <summary>
/// Aspect that, when apply on a class, fully implements the interface
/// <see cref="INotifyPropertyChanged"/> into that class, and overrides all properties to
/// that they raise the event <see cref="INotifyPropertyChanged.PropertyChanged"/>.
/// </summary>
[Serializable]
[IntroduceInterface(typeof(INotifyPropertyChanged),
OverrideAction = InterfaceOverrideAction.Ignore)]
[MulticastAttributeUsage(MulticastTargets.Class | MulticastTargets.Property,
Inheritance = MulticastInheritance.Strict)]
public sealed class NotifyPropertyChangedAttribute : InstanceLevelAspect,
INotifyPropertyChanged
{
/// <summary>
/// Field bound at runtime to a delegate of the method OnPropertyChanged
/// </summary>
[ImportMember("OnPropertyChanged", IsRequired = false)]
public Action<string> OnPropertyChangedMethod;
/// <summary>
/// Method introduced in the target type (unless it is already present);
/// raises the <see cref="PropertyChanged"/> event.
/// </summary>
/// <param name="propertyName">Name of the property.</param>
[IntroduceMember(Visibility = Visibility.Family, IsVirtual = true,
OverrideAction = MemberOverrideAction.Ignore)]
public void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this.Instance,
new PropertyChangedEventArgs(propertyName));
}
}
/// <summary>
/// Event introduced in the target type (unless it is already present);
/// raised whenever a property has changed.
/// </summary>
[IntroduceMember(OverrideAction = MemberOverrideAction.Ignore)]
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Method intercepting any call to a property setter.
/// </summary>
/// <param name="args">Aspect arguments.</param>
[OnLocationSetValueAdvice,
MulticastPointcut( Targets = MulticastTargets.Property,
Attributes = MulticastAttributes.Instance)]
public void OnPropertySet(LocationInterceptionArgs args)
{
// Don't go further if the new value is equal to the old one.
// (Possibly use object.Equals here).
if (args.Value == args.GetCurrentValue())
{
return;
}
// Actually sets the value.
args.ProceedSetValue();
// Invoke method OnPropertyChanged (our, the base one, or the overridden one).
this.OnPropertyChangedMethod.Invoke(args.Location.Name);
}
}
如果希望所有属性都实现
NotifyPropertyChanged
,则此属性也可以应用于类级别。关于这个例子的更多信息可以找到PostSharp看起来很有希望,但我最终使用了pwas的Fody答案。主要是因为PostSharp不是免费的。谢谢你的意见!
[NotifyPropertyChanged]
public WorkspaceViewModel CurrentTab { get; set; }