c# - 触发 OnPropertyChanged 的​​更好方法

标签 c# wpf

我们有一个遵循 MVVM 模式的 WPF 项目。

在 View 模型中有很多代码看起来像这样:

    private string m_Fieldname;
    public string Fieldname
    {
        get { return m_Fieldname; }
        set
        {
            m_Fieldname = value;
            OnPropertyChanged("Fieldname");
        }
    }

有没有一种方法可以用更少的代码来做到这一点?

像这样的东西会很好:

[NotifyWhenChanged]
public string Fieldname { get; set ; }

最佳答案

你可以看看PostSharp .他们甚至在 Data Binding 处有 sample .从那里获取的代码:

/// <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 );

    }
}

用法就这么简单:

[NotifyPropertyChanged]
public class Shape
{
   public double X { get; set; }
   public double Y { get; set; }
}

从 PostSharp 站点获取并插入以完成答案的示例

关于c# - 触发 OnPropertyChanged 的​​更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7063902/

相关文章:

c# - 在新应用程序域上创建动态程序集

.net - 有人在真正的LOB应用程序中使用WPF吗?

C# 可以在列表框中显示图像吗?

c# - 获取Linq to SQL保存到数据库

wpf - 将空字符串绑定(bind)到组合框

wpf - 如何检测WPF客户端应用程序是否脱机?

c# - 应用程序在 Dispatcher.Invoke 后卡住

c# - 如何在 WPF DataGrid 中显示波斯日期?

c# - 使用 C# 在 MongoDB 中使用 IsoDate 和 DateTime

c# - LINQ 操作是否返回与正在操作的集合具有相同索引的集合?