### Install PropertyChanged.Fody NuGet Package Source: https://github.com/fody/propertychanged/blob/master/readme.md Install the PropertyChanged.Fody NuGet package and the Fody NuGet package. Fody must be installed to ensure the use of the latest version. ```powershell PM> Install-Package Fody PM> Install-Package PropertyChanged.Fody ``` -------------------------------- ### Person Class Example Source: https://github.com/fody/propertychanged/wiki/NotificationInterception A sample class implementing `INotifyPropertyChanged` that will have its `OnPropertyChanged` calls intercepted. ```csharp public class Person : INotifyPropertyChanged { public string Name { get; set; } public event PropertyChangedEventHandler PropertyChanged; } ``` -------------------------------- ### Example Person Class Source: https://github.com/fody/propertychanged/wiki/MVVMLightBroadcast A simple model class demonstrating inheritance from a base class that handles property changed notifications. ```csharp public class Person : MyBaseClass { public string Name { get; set; } } ``` -------------------------------- ### Basic Model Class with IsChanged Property Source: https://github.com/fody/propertychanged/wiki/Implementing-An-IsChanged-Flag Defines a simple C# class 'Person' that implements INotifyPropertyChanged and includes a basic 'IsChanged' property. This serves as the starting point before compilation. ```csharp public class Person : INotifyPropertyChanged { public string Name { get; set; } public bool IsChanged { get; set; } public event PropertyChangedEventHandler PropertyChanged; } ``` -------------------------------- ### Example of AlsoNotifyForAttribute Source: https://github.com/fody/propertychanged/wiki/Attributes Use AlsoNotifyFor to trigger notifications for a different property when a specified property changes. This is useful for computed properties or when multiple properties contribute to a single logical value. ```csharp public class Person : INotifyPropertyChanged { [AlsoNotifyFor("FullName")] public string GivenName { get; set; } [AlsoNotifyFor("FullName")] public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; public string FullName { get; set; } } ``` -------------------------------- ### Code Generator Configuration in Project File Source: https://github.com/fody/propertychanged/blob/master/readme.md Configure the PropertyChanged.Fody code generator by setting properties in your project file. This example shows how to disable the generator and customize the event invoker name. ```xml false OnPropertyChanged ``` -------------------------------- ### Example of OnChangedMethodAttribute Source: https://github.com/fody/propertychanged/wiki/Attributes Use OnChangedMethod to specify a method that should be automatically called after a property's value has changed. This allows for custom logic to be executed in response to property updates. ```csharp public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; [OnChangedMethod(nameof(OnMyNameChanged))] public string Name { get; set; } private void OnMyNameChanged() { Debug.WriteLine("Name changed"); } } ``` -------------------------------- ### Example of DependsOnAttribute Source: https://github.com/fody/propertychanged/wiki/Attributes Use DependsOn to specify that a property should be notified when any of its dependent properties are set. This ensures that computed properties are updated when their underlying data changes. ```csharp public class Person : INotifyPropertyChanged { public string GivenName { get; set; } public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; [DependsOn("GivenName","FamilyName")] public string FullName { get; set; } } ``` -------------------------------- ### Example of DoNotSetChangedAttribute Source: https://github.com/fody/propertychanged/wiki/Attributes Apply DoNotSetChanged to a property to prevent the `IsChanged` flag from being updated when that specific property's value is set. This is useful for properties that should not affect the overall changed state of the object. ```csharp public class Person: INotifyPropertyChanged { [DoNotSetChanged] public string FullName { get; set; } public bool IsChanged { get; set; } public event PropertyChangedEventHandler PropertyChanged; } ``` -------------------------------- ### Example of DoNotNotifyAttribute Source: https://github.com/fody/propertychanged/wiki/Attributes Apply DoNotNotify to a property or type to prevent Fody's PropertyChanged weaver from injecting notification logic for it. This is useful for properties that do not require change notifications or to opt out specific types. ```csharp public class Person : INotifyPropertyChanged { public string GivenName { get; set; } [DoNotNotify] public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; } ``` -------------------------------- ### Passing Old and New Values to OnPropertyNameChanged Source: https://github.com/fody/propertychanged/wiki/On_PropertyName_Changed Demonstrates how to define OnPropertyNameChanged methods that accept old and new values. The parameters can be of type 'object' or the same type as the property, but both must match. ```csharp public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; [OnChangedMethod(nameof(OnName1Changed))] public string Name1 { get; set; } private void OnName1Changed(object oldValue, object newValue) { Debug.WriteLine("Name Changed:" + oldValue + " => " + newValue); } [OnChangedMethod(nameof(OnName2Changed))] public string Name2 { get; set; } private void OnName2Changed(string oldValue, string newValue) { Debug.WriteLine("Name Changed:" + oldValue + " => " + newValue); } } ``` -------------------------------- ### Before PropertyChanged Injection Source: https://github.com/fody/propertychanged/blob/master/readme.md This code shows a class implementing INotifyPropertyChanged before Fody.PropertyChanged is applied. It manually defines properties and the event. ```csharp public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public string GivenNames { get; set; } public string FamilyName { get; set; } public string FullName => $"{GivenNames} {FamilyName}"; } ``` -------------------------------- ### Basic Class Structure for Code Generation Source: https://github.com/fody/propertychanged/blob/master/readme.md Mark a class implementing INotifyPropertyChanged or having the [AddINotifyPropertyChangedInterface] attribute as partial. The generator will add the necessary event and event-invokers. ```csharp public partial class Class1 : INotifyPropertyChanged { public int Property1 { get; set; } public int Property2 { get; set; } } ``` -------------------------------- ### Compile-time Generated Property Setter with Before/After Source: https://github.com/fody/propertychanged/wiki/BeforeAfter This is the compiled output demonstrating how the property setter is automatically generated to capture the 'before' value and invoke the OnPropertyChanged method with both 'before' and 'after' values. ```csharp public class Person : INotifyPropertyChanged { private string name; public event PropertyChangedEventHandler PropertyChanged; public string Name { get { return name; } set { object before = Name; name = value; OnPropertyChanged("Name", before, Name); } } public void OnPropertyChanged(string propertyName, object before, object after) { //Perform property validation var propertyChanged = PropertyChanged; if (propertyChanged != null) { propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } ``` -------------------------------- ### Compiled Code with IsChanged Logic Source: https://github.com/fody/propertychanged/wiki/Implementing-An-IsChanged-Flag Illustrates the compiled C# code for the 'Person' class, showing how the 'IsChanged' flag is automatically set to true within the setter of the 'Name' property. This demonstrates the core functionality. ```csharp public class Person : INotifyPropertyChanged { string name; bool isChanged; public string Name { get => name; set { if (name != value) { name = value; IsChanged = true; OnPropertyChanged(InternalEventArgsCache.Name); } } } public bool IsChanged { get => isChanged; set { if (isChanged != value) { isChanged = value; OnPropertyChanged(InternalEventArgsCache.IsChanged); } } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } ``` -------------------------------- ### Implement OnPropertyChanged with Before/After Values Source: https://github.com/fody/propertychanged/wiki/BeforeAfter Override the OnPropertyChanged method to accept 'before' and 'after' parameters. This allows for direct access to property values during change notification, useful for validation or complex state management. ```csharp public void OnPropertyChanged(string propertyName, object before, object after) { //Perform property validation var propertyChanged = PropertyChanged; if (propertyChanged != null) { propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } ``` -------------------------------- ### Workaround for WPF Projects Targeting Multiple Frameworks Source: https://github.com/fody/propertychanged/blob/master/readme.md This build target can be added to your WPF project to resolve compilation errors related to duplicate 'OnPropertyChanged' members when targeting multiple frameworks. ```xml ``` -------------------------------- ### Property Setter with Equality Check Source: https://github.com/fody/propertychanged/wiki/EqualityChecking This C# code demonstrates a typical property setter where an equality check is performed before updating the backing field and invoking `OnPropertyChanged`. If the new value is equal to the current value, the method returns early. ```csharp public string Property1 { get { return property1; } set { if (String.Equals(property1, value)) return; property1 = value; OnPropertyChanged("Property1"); } } ``` -------------------------------- ### Generated Code for Partial Generic Class Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialGenericClassWithoutEventHandler.verified.txt This C# code demonstrates the structure of generated code for a partial generic class. It includes the necessary events and methods for property change notifications, as generated by PropertyChanged.Fody. ```csharp // PropertyChanged.g.cs // #nullable enable #pragma warning disable CS0067 #pragma warning disable CS8019 using System.Diagnostics; using System.CodeDom.Compiler; using System.ComponentModel; using System.Runtime.CompilerServices; partial class Class1 { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } ``` -------------------------------- ### Generated Code for Class2 (Root Namespace) Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForClassesInMultipleNamespaces.verified.txt This snippet shows the generated code for Class2 in the root namespace, which does not implement INotifyPropertyChanged directly but has the necessary methods. ```csharp partial class Class2 { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } ``` -------------------------------- ### Generated Code for Class2a (Namespace2.Namespace3) Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForClassesInMultipleNamespaces.verified.txt This snippet shows the generated code for Class2a within the nested Namespace2.Namespace3, which does not implement INotifyPropertyChanged directly but has the necessary methods. ```csharp namespace Namespace2.Namespace3 { partial class Class2a { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } } ``` -------------------------------- ### Generated PropertyChanged Implementation for Partial Class Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialClassWithAttributeInFileScopedNamespace.verified.txt This code is automatically generated by PropertyChanged.Fody for a partial class implementing INotifyPropertyChanged. It includes the PropertyChanged event and the OnPropertyChanged methods. Ensure the class is marked as partial and has the necessary attributes. ```csharp // PropertyChanged.g.cs // #nullable enable #pragma warning disable CS0067 #pragma warning disable CS8019 using System.Diagnostics; using System.CodeDom.Compiler; using System.ComponentModel; using System.Runtime.CompilerServices; namespace Whatever { partial class Class1 : INotifyPropertyChanged { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } } ``` -------------------------------- ### Generated Code for Top-Level Partial Class Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForNestedPartialClasses.verified.txt This snippet shows the generated code for a top-level partial class that implements INotifyPropertyChanged. It includes the PropertyChanged event and the OnPropertyChanged methods. ```csharp // PropertyChanged.g.cs // #nullable enable #pragma warning disable CS0067 #pragma warning disable CS8019 using System.Diagnostics; using System.CodeDom.Compiler; using System.ComponentModel; using System.Runtime.CompilerServices; partial class Class1 : INotifyPropertyChanged { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } partial class Class1 { partial class Class2 { partial class Class3 { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } } } ``` -------------------------------- ### Use Base Equals for Equality Checks Source: https://github.com/fody/propertychanged/wiki/Options Control if equality checks use the Equals method resolved from the base class. Set to 'false' to disable this behavior. ```xml ``` -------------------------------- ### After PropertyChanged Injection Source: https://github.com/fody/propertychanged/blob/master/readme.md This code demonstrates the compiled output after Fody.PropertyChanged has processed the class. It includes injected logic for property setters to invoke OnPropertyChanged. ```csharp public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; string givenNames; public string GivenNames { get => givenNames; set { if (value != givenNames) { givenNames = value; OnPropertyChanged(InternalEventArgsCache.GivenNames); OnPropertyChanged(InternalEventArgsCache.FullName); } } } string familyName; public string FamilyName { get => familyName; set { if (value != familyName) { familyName = value; OnPropertyChanged(InternalEventArgsCache.FamilyName); OnPropertyChanged(InternalEventArgsCache.FullName); } } } public string FullName => $"{GivenNames} {FamilyName}"; protected void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } internal static class InternalEventArgsCache { internal static PropertyChangedEventArgs FamilyName = new PropertyChangedEventArgs("FamilyName"); internal static PropertyChangedEventArgs FullName = new PropertyChangedEventArgs("FullName"); internal static PropertyChangedEventArgs GivenNames = new PropertyChangedEventArgs("GivenNames"); } ``` -------------------------------- ### Generated Code for Class2 (Namespace1) Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForClassesInMultipleNamespaces.verified.txt This snippet shows the generated code for Class2 within Namespace1, which does not implement INotifyPropertyChanged directly but has the necessary methods. ```csharp namespace Namespace1 { partial class Class2 { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } } ``` -------------------------------- ### Original Class Implementing INotifyPropertyChanged Source: https://github.com/fody/propertychanged/wiki/ExampleUsage This is the original C# class that implements the INotifyPropertyChanged interface. It defines properties and the PropertyChanged event. ```csharp public class Person : INotifyPropertyChanged { public string GivenName { get; set; } public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; public string FullName { get { return GivenName + " " + FamilyName; } } } ``` -------------------------------- ### Compiled Person Class with Interception Source: https://github.com/fody/propertychanged/wiki/NotificationInterception This shows how the `Person` class is compiled with `PropertyChangedNotificationInterceptor` integrated into its `OnPropertyChanged` method. ```csharp public class Person : INotifyPropertyChanged { private string name; public event PropertyChangedEventHandler PropertyChanged; public virtual void InnerOnPropertyChanged(string propertyName) { var propertyChanged = PropertyChanged; if (propertyChanged != null) { propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } public virtual void OnPropertyChanged(string propertyName) { Action action = () => InnerOnPropertyChanged(propertyName); PropertyChangedNotificationInterceptor.Intercept(this, action, propertyName); } public string Name { get { return name; } set { name = value; OnPropertyChanged("Name"); } } } ``` -------------------------------- ### Base ViewModel with Broadcast Method Source: https://github.com/fody/propertychanged/wiki/MVVMLightBroadcast Extends GalaSoft.MvvmLight.ViewModelBase to include a protected Broadcast method. This method sends a PropertyChangedMessage via the Messenger. ```csharp public class MyBaseClass : GalaSoft.MvvmLight.ViewModelBase { protected virtual void Broadcast(object oldValue, object newValue, string propertyName) { var message = new PropertyChangedMessage(this, this, oldValue, newValue, propertyName); if (MessengerInstance != null) { MessengerInstance.Send(message); } else { GalaSoft.MvvmLight.Messaging.Messenger.Default.Send(message); } } protected virtual void RaisePropertyChanged(string propertyName, object oldValue, object newValue) { RaisePropertyChanged(propertyName); Broadcast(oldValue, newValue, propertyName); } } ``` -------------------------------- ### Generated Code for Class1 (Namespace1) Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForClassesInMultipleNamespaces.verified.txt This snippet shows the generated code for Class1 within Namespace1, implementing INotifyPropertyChanged. ```csharp namespace Namespace1 { partial class Class1 : INotifyPropertyChanged { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } } ``` -------------------------------- ### Generated PropertyChanged Event and OnPropertyChanged Methods Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForDeepNestedItems.verified.txt This code demonstrates the generated `PropertyChanged` event and the `OnPropertyChanged` methods within a deeply nested class structure. These are automatically implemented by the PropertyChanged.Fody analyzer. ```csharp // PropertyChanged.g.cs // #nullable enable #pragma warning disable CS0067 #pragma warning disable CS8019 using System.Diagnostics; using System.CodeDom.Compiler; using System.ComponentModel; using System.Runtime.CompilerServices; partial record Level1 { partial struct Level2 { partial interface Level3 { partial record struct Level4 { partial class Level5 { partial class Class { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } } } } } } ``` -------------------------------- ### Default PropertyChangedNotificationInterceptor Source: https://github.com/fody/propertychanged/wiki/NotificationInterception This is the default implementation of the interceptor. It simply executes the provided `onPropertyChangedAction`. ```csharp public static class PropertyChangedNotificationInterceptor { public static void Intercept( object target, Action onPropertyChangedAction, string propertyName) { onPropertyChangedAction(); } } ``` -------------------------------- ### Generated Code for Class1 (Namespace2) Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForClassesInMultipleNamespaces.verified.txt This snippet shows the generated code for Class1 within Namespace2, implementing INotifyPropertyChanged. ```csharp namespace Namespace2 { partial class Class1 : INotifyPropertyChanged { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } } ``` -------------------------------- ### Intercepting Notification Calls with Before/After Values Source: https://github.com/fody/propertychanged/blob/master/readme.md Use this signature for `OnPropertyChanged` or `OnChanged` to access before and after values during notification interception. ```csharp public void OnPropertyChanged(string propertyName, object before, object after) ``` -------------------------------- ### Generated PropertyChanged Implementation for Nested Class Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForClassesNestedInRecord.verified.txt This code demonstrates the PropertyChanged event and its associated methods generated by PropertyChanged.Fody for a class nested within a record. It includes the event declaration, `OnPropertyChanged` overloads for string property names and `PropertyChangedEventArgs`, and the necessary attributes for code generation and debugging. ```csharp // PropertyChanged.g.cs // #nullable enable #pragma warning disable CS0067 #pragma warning disable CS8019 using System.Diagnostics; using System.CodeDom.Compiler; using System.ComponentModel; using System.Runtime.CompilerServices; partial record Class1 { partial class Class2 { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } } ``` -------------------------------- ### Basic Property with OnPropertyNameChanged Method Source: https://github.com/fody/propertychanged/wiki/On_PropertyName_Changed Defines a class with a property and a corresponding OnPropertyNameChanged method. Fody.PropertyChanged automatically injects a call to this method within the property's setter. ```csharp public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public string Name { get; set; } public void OnNameChanged() { Debug.WriteLine("Name Changed"); } } ``` -------------------------------- ### Custom PropertyChangedMessage Class Source: https://github.com/fody/propertychanged/wiki/MVVMLightBroadcast Defines a custom message for property changes, including old and new values. Inherits from MVVM Light's PropertyChangedMessageBase. ```csharp public class PropertyChangedMessage : GalaSoft.MvvmLight.Messaging.PropertyChangedMessageBase { public PropertyChangedMessage(object sender, object target, object oldValue, object newValue, string propertyName) : base(sender, target, propertyName) { OldValue = oldValue; NewValue = newValue; } public object NewValue { get; set; } public object OldValue { get; set; } } ``` -------------------------------- ### Generated PropertyChanged Implementation for Sealed Partial Class Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedNoneVirtualForSealedPartialClassWithAttribute.verified.txt This code is automatically generated by PropertyChanged.Fody for a sealed partial class implementing INotifyPropertyChanged. It includes the event declaration and methods for invoking the event. ```csharp // PropertyChanged.g.cs // #nullable enable #pragma warning disable CS0067 #pragma warning disable CS8019 using System.Diagnostics; using System.CodeDom.Compiler; using System.ComponentModel; using System.Runtime.CompilerServices; partial class Class1 : INotifyPropertyChanged { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] private void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] private void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } ``` -------------------------------- ### Generated Code for Partial Class Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForPartialClassWithRedundantInterfaceImplementationAndAttributeButNotOnTheFirstPart.verified.txt This snippet shows the code generated by PropertyChanged.Fody for a partial class. It includes the necessary event handlers and methods for property change notifications. ```csharp // PropertyChanged.g.cs // #nullable enable #pragma warning disable CS0067 #pragma warning disable CS8019 using System.Diagnostics; using System.CodeDom.Compiler; using System.ComponentModel; using System.Runtime.CompilerServices; partial class Class1234 { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } ``` -------------------------------- ### Interceptor with Property Values Source: https://github.com/fody/propertychanged/wiki/NotificationInterception Modify the interceptor signature to include `before` and `after` parameters, allowing access to property values during interception. ```csharp public static class PropertyChangedNotificationInterceptor { public static void Intercept(object target, Action onPropertyChangedAction, string propertyName, object before, object after) { onPropertyChangedAction(); } } ``` -------------------------------- ### Compiled Code with PropertyChanged Handled by Fody Source: https://github.com/fody/propertychanged/wiki/ExampleUsage This is the C# code that is compiled after Fody processes the original class. It includes generated backing fields and calls to OnPropertyChanged for each property setter. ```csharp public class Person : INotifyPropertyChanged { private string familyName; private string givenName; public event PropertyChangedEventHandler PropertyChanged; public string FamilyName { get { return familyName; } set { if (!Object.Equals(familyName, value)) { familyName = value; OnPropertyChanged("FamilyName"); OnPropertyChanged("FullName"); } } } public string GivenName { get { return givenName; } set { if (!Object.Equals(givenName, value)) { givenName = value; OnPropertyChanged("GivenName"); OnPropertyChanged("FullName"); } } } public string FullName { get { return GivenName + " " + FamilyName; } } public virtual void OnPropertyChanged(string propertyName) { var propertyChanged = PropertyChanged; if (propertyChanged != null) { propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } ``` -------------------------------- ### Custom AlsoNotifyForAttribute Source: https://github.com/fody/propertychanged/wiki/WeavingWithoutAddingAReference Implement this custom attribute if you prefer not to have a reference to PropertyChanged.dll. It allows specifying properties that should also be notified. ```csharp namespace PropertyChanged { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public class AlsoNotifyForAttribute : Attribute { public AlsoNotifyForAttribute(string property){} public AlsoNotifyForAttribute(string property, params string[] otherProperties){} } } ``` -------------------------------- ### Default Event Invoker Method Source: https://github.com/fody/propertychanged/wiki/EventInvokerSelectionInjection This is the standard implementation of the `OnPropertyChanged` method that fires the `PropertyChanged` event. It checks if the event handler is subscribed before invoking it. ```csharp public virtual void OnPropertyChanged(string propertyName) { var propertyChanged = PropertyChanged; if (propertyChanged != null) { propertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } ``` -------------------------------- ### Generated Code for Nested Class in Struct Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.CodeIsGeneratedForClassesNestedInStruct.verified.txt Shows the C# code generated by PropertyChanged.Fody for a class nested within a struct. Includes event declarations and methods for raising property change notifications. ```csharp // PropertyChanged.g.cs // #nullable enable #pragma warning disable CS0067 #pragma warning disable CS8019 using System.Diagnostics; using System.CodeDom.Compiler; using System.ComponentModel; using System.Runtime.CompilerServices; partial struct Class1 { partial class Class2 { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } } ``` -------------------------------- ### Referencing OnPropertyNameChanged Method with Attribute Source: https://github.com/fody/propertychanged/wiki/On_PropertyName_Changed Uses the [OnChangedMethod] attribute to explicitly link a property to a specific change notification method, helping to avoid compiler warnings and allowing for custom method names. ```csharp public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; [OnChangedMethod(nameof(OnMyNameChanged))] public string Name { get; set; } private void OnMyNameChanged() { Debug.WriteLine("Name changed"); } } ``` -------------------------------- ### Configure EventInvokerNames for PropertyChanged Weaver Source: https://github.com/fody/propertychanged/wiki/Options Customize the names of methods that fire the notify event. Useful when using custom INotifyPropertyChanged implementations. ```xml ``` -------------------------------- ### Generated PropertyChanged Implementation Source: https://github.com/fody/propertychanged/blob/master/PropertyChanged.Fody.Analyzer.Tests/CodeGeneratorTest.NoCodeIsGeneratedForPartialClass2WithAttributeAndAttributedBaseClass.verified.txt This code represents the automatically generated implementation of the INotifyPropertyChanged interface by PropertyChanged.Fody. It includes the event declaration and the OnPropertyChanged methods. This code is typically generated for classes that inherit from INotifyPropertyChanged and have properties that need to trigger change notifications. ```csharp // PropertyChanged.g.cs // #nullable enable #pragma warning disable CS0067 #pragma warning disable CS8019 using System.Diagnostics; using System.CodeDom.Compiler; using System.ComponentModel; using System.Runtime.CompilerServices; partial class Class1 : INotifyPropertyChanged { [GeneratedCode("PropertyChanged.Fody", "TEST")] public event PropertyChangedEventHandler? PropertyChanged; [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } [GeneratedCode("PropertyChanged.Fody", "TEST"), DebuggerNonUserCode] protected virtual void OnPropertyChanged(PropertyChangedEventArgs eventArgs) { PropertyChanged?.Invoke(this, eventArgs); } } ``` -------------------------------- ### Compiled Code with OnPropertyNameChanged Call Source: https://github.com/fody/propertychanged/wiki/On_PropertyName_Changed Illustrates the compiled output where Fody.PropertyChanged has injected a call to the OnNameChanged method within the property setter, after the value has been updated and before OnPropertyChanged is invoked. ```csharp public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; string name; public string Name { get { return name; } set { if (value != name) { name = value; OnNameChanged(); OnPropertyChanged("Name"); } } } public void OnNameChanged() { Debug.WriteLine("Name Changed"); } public virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } ``` -------------------------------- ### Suppress OnPropertyNameChanged Warning Source: https://github.com/fody/propertychanged/wiki/Options Turn off build warnings related to mismatched On_PropertyName_Changed methods. Set to 'true' to suppress these specific warnings. ```xml ``` -------------------------------- ### Intercept OnPropertyChanged on UI Thread Source: https://github.com/fody/propertychanged/wiki/NotificationInterception Use this interceptor to ensure `OnPropertyChanged` is executed on the UI thread, which is necessary for UI updates in frameworks like WPF or Silverlight. ```csharp public static class PropertyChangedNotificationInterceptor { public static void Intercept(object target, Action onPropertyChangedAction, string propertyName) { Application.Current.Dispatcher.Invoke(onPropertyChangedAction); } } ``` -------------------------------- ### Automatic Property Notification for Computed Properties Source: https://github.com/fody/propertychanged/wiki/PropertyDependencies Demonstrates a class with computed property 'FullName' that depends on 'GivenNames' and 'FamilyName'. PropertyChanged will automatically generate code to call OnPropertyChanged("FullName") when 'GivenNames' or 'FamilyName' are set. ```csharp public class Person : INotifyPropertyChanged { public string GivenNames { get; set; } public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; public string FullName { get { return string.Format("{0} {1}", GivenNames, FamilyName); } } } ``` -------------------------------- ### Disable InjectOnPropertyNameChanged Feature Source: https://github.com/fody/propertychanged/wiki/Options Control whether the On_PropertyName_Changed feature is enabled. Set to 'false' to disable. ```xml ``` -------------------------------- ### Assembly-wide Filtering with FilterType Attribute Source: https://github.com/fody/propertychanged/blob/master/readme.md Use the `FilterType` attribute to scope weaving to specific namespaces. This attribute accepts a Regex pattern for namespace matching. Multiple filters can be applied. ```csharp [assembly: PropertyChanged.FilterType("My.Specific.OptIn.Namespace.")] ``` -------------------------------- ### Field-Based Property Notification for Computed Properties Source: https://github.com/fody/propertychanged/wiki/PropertyDependencies Illustrates a class using private fields for properties 'GivenNames' and 'FamilyName'. The computed property 'FullName' depends on these fields. PropertyChanged will automatically generate code to call OnPropertyChanged("FullName") when the setters for 'GivenNames' or 'FamilyName' are invoked. ```csharp public class Person : INotifyPropertyChanged { string givenNames; string familyName; public event PropertyChangedEventHandler PropertyChanged; public string GivenNames { get { return givenNames; } set { givenNames = value; } } public string FamilyName { get { return familyName; } set { familyName = value; } } public string FullName { get { return string.Format("{0} {1}", givenNames, familyName); } } } ``` -------------------------------- ### Add PropertyChanged to FodyWeavers.xml Source: https://github.com/fody/propertychanged/blob/master/readme.md Add the PropertyChanged weaver to your FodyWeavers.xml configuration file. This enables the PropertyChanged.Fody functionality. ```xml ``` -------------------------------- ### Custom DoNotCheckEqualityAttribute Source: https://github.com/fody/propertychanged/wiki/WeavingWithoutAddingAReference Implement this custom attribute to bypass equality checks for properties or fields when not referencing PropertyChanged.dll. ```csharp namespace PropertyChanged { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] public class DoNotCheckEqualityAttribute : Attribute { } } ``` -------------------------------- ### Custom DependsOnAttribute Source: https://github.com/fody/propertychanged/wiki/WeavingWithoutAddingAReference Implement this custom attribute to define property dependencies when not referencing PropertyChanged.dll. It specifies which properties a given property depends on. ```csharp namespace PropertyChanged { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public class DependsOnAttribute : Attribute { public DependsOnAttribute(string dependency){} public DependsOnAttribute(string dependency, params string[] otherDependencies){} } } ``` -------------------------------- ### Custom DoNotNotifyAttribute Source: https://github.com/fody/propertychanged/wiki/WeavingWithoutAddingAReference Implement this custom attribute to prevent notification for specific classes, properties, or fields when not referencing PropertyChanged.dll. ```csharp namespace PropertyChanged { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public class DoNotNotifyAttribute : Attribute { } } ``` -------------------------------- ### Suppress Build Warnings from PropertyChanged Weaver Source: https://github.com/fody/propertychanged/wiki/Options Turn off build warnings generated by this weaver. Set to 'true' to suppress warnings. ```xml ``` -------------------------------- ### Customizing Event Invoker Name in Weaver Configuration Source: https://github.com/fody/propertychanged/wiki/EventInvokerSelectionInjection Configure PropertyChanged.Fody to use a custom method name for invoking the PropertyChanged event by specifying `EventInvokerNames` in the weaver configuration. ```xml ``` -------------------------------- ### Disable Equality Checking with PropertyChanged Weaver Source: https://github.com/fody/propertychanged/wiki/Options Control if equality checks are created. Set to 'false' to disable equality checking for the project. ```xml ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.