{"id":13629362,"url":"https://github.com/canton7/PropertyChanged.SourceGenerator","last_synced_at":"2025-04-17T09:33:29.865Z","repository":{"id":42981881,"uuid":"380163622","full_name":"canton7/PropertyChanged.SourceGenerator","owner":"canton7","description":"Powerful INotifyPropertyChanged / INotifyPropertyChanging Source Generator, which generates INPC boilerplate for you as part of your build. Supports features such as automatic and manual dependencies between properties, notifications when specific properties change, and more.","archived":false,"fork":false,"pushed_at":"2025-01-13T10:22:06.000Z","size":516,"stargazers_count":147,"open_issues_count":3,"forks_count":17,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-15T04:51:33.608Z","etag":null,"topics":["csharp-sourcegenerator","inotifypropertychanged","inotifypropertychanging","source-generator"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/canton7.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-06-25T07:45:25.000Z","updated_at":"2025-03-18T21:07:23.000Z","dependencies_parsed_at":"2024-01-06T02:10:11.513Z","dependency_job_id":"70c1b3ce-ab4d-417b-a654-a332806746f4","html_url":"https://github.com/canton7/PropertyChanged.SourceGenerator","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canton7%2FPropertyChanged.SourceGenerator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canton7%2FPropertyChanged.SourceGenerator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canton7%2FPropertyChanged.SourceGenerator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canton7%2FPropertyChanged.SourceGenerator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/canton7","download_url":"https://codeload.github.com/canton7/PropertyChanged.SourceGenerator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249331628,"owners_count":21252619,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp-sourcegenerator","inotifypropertychanged","inotifypropertychanging","source-generator"],"created_at":"2024-08-01T22:01:08.540Z","updated_at":"2025-04-17T09:33:29.554Z","avatar_url":"https://github.com/canton7.png","language":"C#","readme":"![Project Icon](https://raw.githubusercontent.com/canton7/PropertyChanged.SourceGenerator/master/icon-small.png) PropertyChanged.SourceGenerator\n===============================================================\n\n[![NuGet](https://img.shields.io/nuget/v/PropertyChanged.SourceGenerator.svg)](https://www.nuget.org/packages/PropertyChanged.SourceGenerator/) [![Build status](https://ci.appveyor.com/api/projects/status/r989lw0mclb6jmja?svg=true)](https://ci.appveyor.com/project/canton7/propertychanged-sourcegenerator)\n\nImplementing `INotifyPropertyChanged` / `INotifyPropertyChanging` is annoying. PropertyChanged.SourceGenerator hooks into your compilation process to generate the boilerplate for you, automatically.\n\nPropertyChanged.SourceGenerator works well if you're using an MVVM framework or going without, and supports various time-saving features such as:\n\n - Automatically notifying dependent properties.\n - Calling hooks when particular properties change.\n - Keeping track of whether any properties have changed.\n\n### Table of Contents\n\n1. [Installation](#installation)\n1. [Quick Start](#quick-start)\n1. [Versioning](#versioning)\n1. [Defining your ViewModel](#defining-your-viewmodel)\n1. [Defining Properties](#defining-properties)\n   1. [Property Names](#property-names)\n   1. [Property Accessibility](#property-accessibility)\n   1. [Property Doc Comments](#property-doc-comments)\n   1. [Attributes on Generated Properties](#attributes-on-generated-properties)\n1. [Property Dependencies](#property-dependencies)\n   1. [Automatic Dependencies](#automatic-dependencies)\n   1. [Manual Dependencies with `[DependsOn]`](#manual-dependencies-with-dependson)\n   1. [Manual Dependencies with `[AlsoNotify]`](#manual-dependencies-with-alsonotify)\n1. [Property Changed Hooks](#property-changed-hooks)\n   1. [Type Hooks with `OnPropertyChanged` / `OnPropertyChanging`](#type-hooks-with-onanypropertychanged--onanypropertychanging)\n   1. [Property Hooks with `On{PropertyName}Changed` / `On{PropertyName}Changing`](#property-hooks-with-onpropertynamechanged--onpropertynamechanging)\n1. [Change Tracking with `[IsChanged]`](#change-tracking-with-ischanged)\n1. [Configuration](#configuration)\n   1. [Generated Property Names](#generated-property-names)\n   1. [`OnPropertyChanged` / `OnPropertyChanging` Method Name](#onpropertychanged--onpropertychanging-method-name)\n   1. [Automatic Dependencies](#automatic-dependencies-1)\n1. [Contributing](#contributing)\n1. [Comparison to PropertyChanged.Fody](#comparison-to-propertychangedfody)\n\n\nInstallation\n------------\n\n[PropertyChanged.SourceGenerator is available on NuGet](https://www.nuget.org/packages/PropertyChanged.SourceGenerator). You'll need to be running Visual Studio 2019 16.9 or higher, or by building using the .NET SDK 5.0.200 or higher (your project doesn't have to target .NET 5, you just need to be building using a newish version of the .NET SDK).\n\nThese dependencies may change in future minor versions, see [Versioning](#versioning).\n\nIf you're using Visual Studio 17.2.6 with WPF and you get lots of \"... already contains a definition for ...\" error messages, [see this bug and workaround](https://github.com/dotnet/wpf/issues/6792#issuecomment-1183633402).\n\n\nQuick Start\n-----------\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel\n{\n    [Notify] private string _lastName;\n    public string FullName =\u003e $\"Dr. {LastName}\";\n}\n```\n\nMake sure your ViewModel is `partial`, and define the backing fields for your properties, decorated with `[Notify]`. When you build your project, PropertyChanged.SourceGenerator will create a partial class which looks something like:\n\n```cs\npartial class MyViewModel : INotifyPropertyChanged\n{\n    public event PropertyChangedEventHandler PropertyChanged;\n\n    public string LastName\n    {\n        get =\u003e _lastName;\n        set\n        {\n            if (!EqualityComparer\u003cstring\u003e.Default.Equals(_lastName, value))\n            {\n                _lastName = value;\n                OnPropertyChanged(EventArgsCache.LastName);\n                OnPropertyChanged(EventArgsCache.FullName);\n            }\n        }\n    }\n\n    protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)\n    {\n        PropertyChanged?.Invoke(args);\n    }\n}\n```\n\nWhat happened there?\n\n1. PropertyChanged.SourceGenerator spotted that you defined a partial class and at least one property was decorated with `[Notify]`, so it got involved and generated another part to the partial class.\n2. It noticed that you hadn't implemented `INotifyPropertyChanged`, so it implemented it for you (it's also fine if you implement it yourself).\n3. For each field decorated with `[Notify]`, it generated property with the same name (but with the leading `_` removed and the first letter capitalised) which used that field as its backing field. That property implemented `INotifyPropertyChanged`.\n4. It noticed that `FullName` depended on `LastName`, so raised the `PropertyChanged` event for `FullName` whenever `LastName` changed.\n\n**Note**: It's really important that you don't refer to the backing fields after you've defined them: let PropertyChanged.SourceGenerator generate the corresponding properties, and then always use those propertues.\n\n\nVersioning\n----------\n\nSource Generators are a relatively new technology, and they're being improved all the time. Unfortunately, in order for source generators to take advantage of improvements, they must target a newer version of Visual Studio / the .NET SDK.\n\nIf/when PropertyChanged.SourceGenerator is updated to depend on a new version Visual Studio / the .NET SDK, this will be signified by a **minor version bump**: the minor version number will be incremented. Changes which mean you have to change existing *code* to keep PropertyChanged.SourceGenerator working will be signified by a **major version bump**.\n\n\n| Version Number | Min Visual Studio Version | Min .NET SDK Version |\n|----------------|---------------------------|----------------------|\n| 1.0.x | 2019 16.9 | 5.0.200 |\n| 1.1.x | 2022 17.3 | 6.0.304 |\n\n\nDefining your ViewModel\n-----------------------\n\n### `INotifyPropertyChanged`\n\nWhen you define a ViewModel which makes use of PropertyChanged.SourceGenerator, that ViewModel must be `partial`. If it isn't, you'll get a warning.\n\nYour ViewModel can implement `INotifyPropertyChanged`, or not, or it can implement parts of it (such as implementing the interface but not defining the `PropertyChanged` event), or it can extend from a base class which implements `INotifyPropertyChanged`: PropertyChanged.SourceGenerator will figure it out and fill in the gaps.\n\nIf you've got a `ViewModel` base class which implements `INotifyPropertyChanged` (perhaps as part of an MVVM framework), PropertyChanged.SourceGenerator will try and find a suitable method to call in order to raise the `PropertyChanged` event. It will look for a method called `OnPropertyChanged`, `RaisePropertyChanged`, `NotifyOfPropertyChange`, or `NotifyPropertyChanged`, which covers all of the major MVVM frameworks (although this is configurable, see [Configuration](#configuration)), with one of the following signatures:\n\n - `void OnPropertyChanged(PropertyChangedEventArgs args)`\n - `void OnPropertyChanged(string propertyName)`\n - `void OnPropertyChanged(PropertyChangedEventArgs args, object oldValue, object newValue)`\n - `void OnPropertyChanged(string propertyName, object oldValue, object newValue)`\n\nIf it can't find a suitable method, you'll get a warning and it won't run on that particular ViewModel.\n\n### `INotifyPropertyChanging`\n\nWorking with `INotifyPropertyChanging` is similar, with the caveat that your class or one of its base classes must implement `INotifyPropertyChanging` (not everone wants to implement this interface, so it's opt-in). You don't need to implement all of the interface members: PropertyChanged.SourceGenerator will step in and fill in the gaps.\n\nAs with `INotifyPropertyChanged`, PropertyChanged.SourceGenerator will try and find a suitable method to call in order to raise the `PropertyChanging` event. It will look for a method called `OnPropertyChanging`, `RaisePropertyChanging`, `NotifyOfPropertyChanging`, or `NotifyPropertyChanging` (again this is configurable, see [Configuration](#configuration)), with one of the following signatures:\n\n - `void OnPropertyChanging(PropertyChangingEventArgs args)`\n - `void OnPropertyChanging(string propertyName)`\n - `void OnPropertyChanging(PropertyChangingEventArgs args, object oldValue)`\n - `void OnPropertyChanging(string propertyName, object oldValue)`\n\n\nDefining Properties\n-------------------\n\nTo get PropertyChanged.SourceGenerator to generate a property which implements `INotifyPropertyChanged`, you must define the backing field for that property, and decorate it with `[Notify]`.\n\n(This is an annoying effect of how Source Generators work. If you'd like a better way, please [vote for this issue on partial properties](https://github.com/dotnet/csharplang/discussions/3412)).\n\nIf you write:\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel : INotifyPropertyChanged\n{\n    [Notify] private int _foo;\n}\n```\n\nPropertyChanged.SourceGenerator will generate something like:\n\n```cs\npartial class MyViewModel\n{\n    public int Foo\n    {\n        get =\u003e _foo,\n        set\n        {\n            if (!EqualityComparer\u003cint\u003e.Default.Equals(_foo, value))\n            {\n                _foo = value;\n                OnPropertyChanged(EventArgsCache.Foo);\n            }\n        }\n    }\n\n    // PropertyChanged event, OnPropertyChanged method, etc.\n}\n```\n\n\n### Property Names\n\nThe name of the generated property is derived from the name of the backing field, by:\n\n1. Removing a `_` prefix, if one exists\n2. Changing the first letter to upper-case\n\nThis can be customised, see [Configuration](#configuration).\n\nIf you want to manually specify the name of a particular property, you can pass a string to `[Notify]`:\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel : INotifyPropertyChanged\n{\n    [Notify(\"FOO\")] private int _foo;\n}\n```\n\nPropertyChanged.SourceGenerator will generate a property called `FOO`.\n\n\n### Property Accessibility\n\nBy default, all generated properties have public getters and public setters.\n\nThis isn't always what you want, so it's possible to override this by passing `Getter.XXX` and `Setter.XXX` to `[Notify]`.\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel : INotifyPropertyChanged\n{\n    [Notify(Setter.Private)]\n    private int _foo;\n\n    [Notify(Getter.PrivateProtected, Setter.Protected)]\n    private string _bar;\n}\n```\n\nThis generates:\n\n```cs\npartial class MyViewModel\n{\n    public int Foo\n    {\n        get =\u003e _foo\n        private set { /* ... */ }\n    }\n\n    protected string Bar\n    {\n        private protected get =\u003e _bar,\n        set { /* ... */ }\n    }\n}\n```\n\n\n### Property Doc Comments\n\nAny XML doc comments applied to your field will be copied to the generated property. Note that any such comments must appear *before* the `[Notify]` attribute.\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel\n{\n    /// \u003csummary\u003e\n    /// The Foo property\n    /// \u003c/summary\u003e\n    [Notify] private int _foo;\n}\n```\n\nGenerates:\n\n```cs\npartial class MyViewModel\n{\n    /// \u003csummary\u003e\n    /// The Foo property\n    /// \u003c/summary\u003e\n    public int Foo\n    {\n        // ...\n    }\n}\n```\n\n\n### Attributes on Generated Properties\n\nSometimes you need the to place attributes onto the generated property, e.g. to control validation or serialization. You can do this by passing a string containing this attribute to the `[PropertyAttribute]` attribute, e.g.:\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel\n{\n    [PropertyAttribute(\"[System.Xml.Serialization.XmlIgnore]\")]\n    [Notify] private int _foo;\n}\n```\n\nThe string that you pass to `[PropertAttribute]` will be pasted into the generated file verbatim. It's important to note that the generated file doesn't have any `using` statements, so you need to fully-qualify all types. For example:\n\n```cs\n[PropertyAttribute(\"[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]\")]\n```\n\nrather than just:\n\n```cs\n[PropertyAttribute(\"[EditorBrowsable(EditorBrowsabeState.Never)]\")]\n```\n\n\n### Virtual Properties\n\nIf you want the generated property to be `virtual`, use:\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel : INotifyPropertyChanged\n{\n    [Notify(IsVirtual = true]\n    private int _foo;\n}\n```\n\nGenerates:\n\n```cs\npartial class MyViewModel\n{\n    public virtual int Foo\n    {\n        // ...\n    }\n}\n```\n\n\nProperty Dependencies\n---------------------\n\nSometimes, you have properties which depend on other properties, for example:\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel\n{\n    [Notify] private string _firstName;\n    [Notify] private string _lastName;\n    public string FullName =\u003e $\"{FirstName} {LastName}\";\n}\n```\n\nWhenever `FirstName` or `LastName` is updated, you want to raise a PropertyChanged event for `FullName`, so that the UI also updates the value of `FullName` which is displayed.\n\n\n### Automatic Dependencies\n\nIf a property has a getter which accesses a generated property on the same type, then PropertyChanged.SourceGenerator will automatically raise a PropertyChanged event every time the property it depends on changes.\n\nFor example, if you write:\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel\n{\n    [Notify] private string _lastName;\n    public string FullName =\u003e $\"Dr. {LastName}\";\n}\n```\n\nPropertyChanged.SourceGenerator will notice that the getter for `FullName` accesses the generated `LastName` property, and so it will add code to the `LastName` setter to raise a PropertyChanged event for `FullName` whenever `LastName` is set:\n\n```cs\npartial class MyViewModel : INotifyPropertyChanged\n{\n    public string LastName\n    {\n        get =\u003e _lastName;\n        set\n        {\n            if (!EqualityComparer\u003cstring\u003e.Default.Equals(_lastName, value))\n            {\n                _lastName = value;\n                OnPropertyChanged(EventArgsCache.LastName);\n                OnPropertyChanged(EventArgsCache.FullName); // \u003c-- Here\n            }\n        }\n    }\n}\n```\n\nIf the property being depended on is not being generated by PropertyChanged.SourceGenerator, or is defined in a base class, then PropertyChanged.SourceGenerator handles this by overriding the `OnPropertyChanged` method. For example:\n\n```cs\npublic partial class Base\n{\n    [Notify] private string _firstName;\n}\npublic partial class Derived : Base\n{\n    [Notify] private string _middleName;\n    public string LastName { get; }\n    public string FullName =\u003e $\"{FirstName} {MiddleName} {LastName}\";\n}\n```\n\nThis will generate something like the following `OnPropertyChanged` method for `Derived`:\n\n```cs\npartial class Derived\n{\n    protected override void OnPropertyChanged(PropertyChangedEventArgs eventArgs)\n    {\n        base.OnPropertyChanged(eventArgs);\n        switch (eventArgs.PropertyName)\n        {\n            case \"FirstName\":\n            case \"LastName\":\n                OnPropertyChanged(EventArgsCache.FullName);\n                break;\n        }\n    }\n}\n```\n\nNote that this cannot work for getters which access properties on other types, or on other instances of the current type. Also note that your property getter must reference the generated property and not its backing field (i.e. `LastName`, not `_lastName` above).\n\nAutomatic dependency resolution does not happen if the property is decorated with `[DependsOn(...)]`. Therefore, to disable automatic dependency resolution for a single property, you can decorate it with an empty `[DependsOn]`. To disable automatic dependency resolution across your entire project, set `propertychanged.auto_notify = false` in your .editorconfig, see [Configuration](#configuration).\n\n\n### Manual Dependencies with `[DependsOn]`\n\nIf automatic dependencies aren't working for you, you can also specify dependencies manually using the `[DependsOn]` attribute. `[DependsOn]` takes the names of one or more generated properties, and means that a PropertyChanged event will be raised if any of those properties are set.\n\nFor example:\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel\n{\n    [Notify] private string _firstName;\n    [Notify] private string _lastName;\n\n    [DependsOn(nameof(FirstName), nameof(LastName))]\n    public string FullName { get; set; }\n}\n```\n\nThe generated setters for `FirstName` and `LastName` will raise a PropertyChanged event for `FullName`.\n\nAs with automatic dependencies, `[DependsOn]` can refer to properties in the current class or base classes. It can also refer to properties which don't actually exist, which means you can refer to properties on derived classes as well.\n\n\n### Manual Dependencies with `[AlsoNotify]`\n\n`[AlsoNotify]` is the opposite of `[DependsOn]`: you place it on a backing field which also has `[Notify]`, and PropertyChanged.SourceGenerator will insert code to raise a PropertyChanged for each named property whenever the generated property is set.\n\nThe named property or properties don't have to exist (although you'll get a warning if they don't), and you can raise PropertyChanged events for properties in base classes.\n\nIf you're naming a property which is generated by PropertyChanged.SourceGenerator, make sure you use the name of the generated property, and not the backing field.\n\nFor example:\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel\n{\n    [Notify, AlsoNotify(nameof(FullName))] private string _firstName;\n    [Notify, AlsoNotify(nameof(FullName))] private string _lastName;\n\n    public string FullName { get; set; }\n}\n```\n\n\nProperty Changed Hooks\n----------------------\n\nHooks are a way for you to be told when a generated property is changed, without needing to subscribe to a type's own PropertyChanged event.\n\n\n### Type Hooks with `OnAnyPropertyChanged` / `OnAnyPropertyChanging`\n\n#### `INotifyPropertyChanged`\n\nThe easiest way to be notified when any generated property has changed is to specify an `OnAnyPropertyChanged` method. This is called from the generated `OnPropertyChanged` method.\n\nThis method can have the following signatures, and any accessibility:\n\n```cs\nvoid OnAnyPropertyChanged(string propertyName);\nvoid OnAnyPropertyChanged(string propertyName, object oldValue, object newValue);\n```\n\nIn order for PropertyChanged.SourceGenerator to be able to supply values for `oldValue` and `newValue`, the `OnPropertyChanged` method in your base class must have a signature which also has these parameters.\n\nNote that the `oldValue` might be `null`, if the property is being raised because of a [property dependency](#property-dependencies).\n\n#### `INotifyPropertyChanging`\n\nTo be notified before a generated property changes, you can specify an `OnAnyPropertyChanging` method.\n\nThis method can have the following signatures, and any accessibility:\n\n```cs\nvoid OnAnyPropertyChanged(string propertyName);\nvoid OnAnyPropertyChanged(string propertyName, object oldValue);\n```\n\nIn order for PropertyChanged.SourceGenerator to be able to supply values for `oldValue`, the `OnPropertyChanging` method in your base class must have a signature which also has this parameter.\n\nNote that the `oldValue` might be `null`, if the property is being raised because of a [property dependency](#property-dependencies).\n\n### Property Hooks with `On{PropertyName}Changed` / `On{PropertyName}Changing`\n\n#### `INotifyPropertyChanged`\n\nLet's say you have a generated property called `FirstName`. If you define a method called `OnFirstNameChanged` in the same class, that method will be called every time `FirstName` changes.\n\nThis method can have two signatures:\n\n - `On{PropertyName}Changed()`.\n - `On{PropertyName}Changed(T oldValue, T newValue)` where `T` is the type of the property called `PropertyName`.\n\nFor example:\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel\n{\n    [Notify] private string _firstName;\n    [Notify] private string _lastName;\n\n    private void OnFirstNameChanged(string oldValue, string newValue)\n    {\n        // ...\n    } \n\n    private void OnLastNameChanged()\n    {\n        // ...\n    }\n}\n```\n\nNote that `oldValue` might have a value of `default(T)`, if the property is being raised because of a [property dependency](#property-dependencies).\n\n#### `INotifyPropertyChanging`\n\nUsing the example above, if you define a method called `OnFirstNameChanging` in the same class, that method will be called just before `FirstName` changes.\n\nThis method can have two signatures:\n\n - `On{PropertyName}Changing()`.\n - `On{PropertyName}Changing(T oldValue)` where `T` is the type of the property called `PropertyName`.\n\nNote that `oldValue` might have a value of `default(T)`, if the property is being raised because of a [property dependency](#property-dependencies).\n\n## Change tracking with `[IsChanged]`\n\nSometimes you need to keep track of whether any properties on a type have been set.\n\nIf you define a `bool` property and decorate it with `[IsChanged]`, then that property will be set to `true` whenever any generate properties are set. It's then up to you to set it back to `false` when appropriate.\n\nFor example:\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel\n{\n    [IsChanged] public bool IsChanged { get; private set; }\n    [Notify] private string _firstName;\n}\n\nvar vm = new MyViewModel();\nAssert.False(vm.IsChanged);\n\nvm.FirstName = \"Harry\";\nAssert.True(vm.IsChanged);\n```\n\nThat `bool IsChanged` property can also be generated by PropertyChanged.SourceGenerator, if you want a PropertyChanged event to be raised when it changed;\n\n```cs\nusing PropertyChanged.SourceGenerator;\npublic partial class MyViewModel\n{\n    [Notify, IsChanged] private bool _isChanged;\n}\n```\n\n\nConfiguration\n-------------\n\nVarious aspects of PropertyChanged.SourceGenerator's behaviour can be configured through a [`.editorconfig` file](https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options).\n\nIf you have one already, great! If not simply add a file called `.editorconfig` in the folder which contains your `.csproj` file (if you want those settings to apply to a single project), or next to your `.sln` file (to apply them to all projects in the solution). There are various other ways to combine settings from different `.editorconfig` files, see the MSDN documentation.\n\nAll of PropertyChanged.SourceGenerator's settings must be in a `[*.cs]` section.\n\n\n### Generated Property Names\n\nThere are a few settings which control how PropertyChanged.SourceGenerator turns the name of your backing field into the name of the property it generates.\n\n```\n[*.cs]\n\n# A string to add to the beginning of any generated property name\n# Default: ''\npropertychanged.add_prefix =\n\n# A semicolon-delimeted list of values to remove from the beginning of any generated property name, if present\n# Default: '_'\npropertychanged.remove_prefixes = _\n\n# A string to add to the end of any generated property name\n# Default: ''\npropertychanged.add_suffix =\n\n# A semicolon-delimeted list of values to remove from the end of any generated property name\n# Default: ''\npropertychanged.remove_suffixes =\n\n# How the first letter of the generated property name should be capitalised\n# Valid values: none, upper_case, lower_Case\n# Default: upper_case\npropertychanged.first_letter_capitalization = upper_case\n```\n\n\n### `OnPropertyChanged` / `OnPropertyChanging` Method Name\n\nWhen PropertyChanged.SourceGenerator runs, it looks for a suitable pre-existing method which can be used to raise the PropertyChanged and PropertyChanging event. If none is found, it will generate a suitable method itself, if it can.\n\nThe names of the pre-existing methods which it searches for, and the name of the method which it will generate, can be configured.\n\n```\n[*.cs]\n\n# A ';' separated list of method names to search for when finding a method to raise the\n# PropertyChanged event. If none is found, the first name listed here is used to generate one.\n# Default: OnPropertyChanged;RaisePropertyChanged;NotifyOfPropertyChange;NotifyPropertyChanged\npropertychanged.onpropertychanged_method_name = OnPropertyChanged;RaisePropertyChanged;NotifyOfPropertyChange;NotifyPropertyChanged\n\n# A ';' separated list of method names to search for when finding a method to raise the\n# PropertyChanging event. If none is found, the first name listed here is used to generate one.\n# Default: OnPropertyChanging;RaisePropertyChanging;NotifyOfPropertyChanging;NotifyPropertyChanging\npropertychanged.onpropertychanging_method_name = OnPropertyChanging;RaisePropertyChanging;NotifyOfPropertyChanging;NotifyPropertyChanging\n```\n\n\n### Automatic Dependencies\n\nTo disable [automatic property dependency resolution](#automatic-dependencies) across your whole project, set:\n\n```\n[*.cs]\n\n# Whether to enable automatic property dependency resolution\n# Valid values: true, false\n# Default: true\npropertychanged.auto_notify = false \n```\n\nContributing\n------------\n\nIt's great that you want to get involved, thank you! Please [open a discussion](https://github.com/canton7/PropertyChanged.SourceGenerator/discussions/new) before doing any serious amount of work, so we can agree an approach before you get started.\n\nOpen a feature branch based on `develop` (**not** `master`), and make sure that you submit any Pull Requests to the `develop` branch.\n\n\nComparison to PropertyChanged.Fody\n----------------------------------\n\nPropertyChanged.SourceGenerator has the same goals as PropertyChanged.Fody. Here are some of the differences:\n\n - PropertyChanged.Fody is able to rewrite your code, which PropertyChanged.SourceGenerator can only add to it (due to the design of Source Generators). This means that PropertyChanged.Fody is able to insert event-raising code directly into your property setters, whereas PropertyChanged.SourceGenerator needs to generate the whole property itself.\n - PropertyChanged.Fody supports some functionality which PropertyChanged.SourceGenerator does not, such as global interception. Please [let me know](https://github.com/canton7/PropertyChanged.SourceGenerator/discussions/new) if you need a bit of functionality which PropertyChanged.SourceGenerator doesn't yet support.\n - PropertyChanged.SourceGenerator supports some functionality which PropertyChanged.Fody does not, such as letting you define `On{PropertyName}Changed` methods which accept the old and new values of the property.\n - PropertyChanged.Fody uses a variety of methods to locate a suitable method to compare a property's old and new value; PropertyChanged.SourceGenerator just uses `EqualityComparer\u003cT\u003e.Default`.\n - I don't [expect you to pay](https://github.com/Fody/Home/blob/master/pages/licensing-patron-faq.md) to use PropertyChanged.SourceGenerator, and will never close an issue or refuse a contribution because you're not giving me money.\n \n","funding_links":[],"categories":["Content","Source Generators"],"sub_categories":["48. [PropertyChangedSourceGenerator](https://ignatandrei.github.io/RSCG_Examples/v2/docs/PropertyChangedSourceGenerator) , in the [MVVM](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#mvvm) category","XAML / WPF / Avalonia"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanton7%2FPropertyChanged.SourceGenerator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcanton7%2FPropertyChanged.SourceGenerator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanton7%2FPropertyChanged.SourceGenerator/lists"}