조쉬 스미스는 좋은 기사를에있는 대답을 완료 PostSharp 사이트에서 가져온 삽입
[NotifyPropertyChanged]
public class Shape
{
public double X { get; set; }
public double Y { get; set; }
}
예 :
/// <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,
Inheritance = MulticastInheritance.Strict)]
public sealed class NotifyPropertyChangedAttribute : InstanceLevelAspect,
INotifyPropertyChanged
{
/// <summary>
/// Field bound at runtime to a delegate of the method <c>OnPropertyChanged</c>.
/// </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);
}
}
사용법은 다음이만큼 간단합니다 이렇게하려면 DynamicObject를 사용하십시오 here
기본적으로 DynamicObject를 상속 한 다음 TrySetMember에 연결합니다. 불행히도 이전 버전에서는 ContextBoundObject를 사용하는 것이 가능할 수도 있지만 이는 주로 성능 저하를 초래할 수 있으며 주로 remoting \ WCF에 적합합니다.
'if (m_Fieldname! = value) {...}'도 항상 확인하지 않아야하나요? 더 많은 코드입니다.하지만 속성이 변경되지 않으면 'PropertyChanged'키를 올리는 것이 올바르게되지 않는 것 같습니다. –
@Danko, 감사합니다. 좋은 점 –
개인적으로 모든 알림, 동등성 검사, 속성 설정 등을 처리하는 Base ObservableItem 클래스의 SetProperty 메서드가 있습니다. 내 ViewModelBase에서 파생 된 클래스입니다. 여전히 단 하나의 라이너를 가져오고 설정합니다. 또한 코드 스 니펫을 생성하기 위해 코드 스 니펫을 설정하고 빠르고 간단하며 표준화되었습니다. –