{"id":15011662,"url":"https://github.com/nkristek/smaragd","last_synced_at":"2025-08-29T05:10:50.937Z","repository":{"id":143468419,"uuid":"113692750","full_name":"nkristek/Smaragd","owner":"nkristek","description":"A platform-independent, lightweight library for developing .NET applications using the MVVM architecture","archived":false,"fork":false,"pushed_at":"2020-06-13T20:41:49.000Z","size":1112,"stargazers_count":37,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-23T23:27:48.841Z","etag":null,"topics":["csharp","dotnet","dotnet-standard","hacktoberfest","icommand","inotifydataerrorinfo","inotifypropertychanged","inotifypropertychanging","mvvm","mvvm-architecture","mvvm-framework","nuget","nuget-package","viewmodel"],"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/nkristek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-12-09T18:45:05.000Z","updated_at":"2025-02-21T19:28:49.000Z","dependencies_parsed_at":"2023-07-16T07:52:20.161Z","dependency_job_id":null,"html_url":"https://github.com/nkristek/Smaragd","commit_stats":null,"previous_names":["nkristek/mvvmbase"],"tags_count":36,"template":false,"template_full_name":null,"purl":"pkg:github/nkristek/Smaragd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nkristek%2FSmaragd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nkristek%2FSmaragd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nkristek%2FSmaragd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nkristek%2FSmaragd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nkristek","download_url":"https://codeload.github.com/nkristek/Smaragd/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nkristek%2FSmaragd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272632156,"owners_count":24967201,"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","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","dotnet","dotnet-standard","hacktoberfest","icommand","inotifydataerrorinfo","inotifypropertychanged","inotifypropertychanging","mvvm","mvvm-architecture","mvvm-framework","nuget","nuget-package","viewmodel"],"created_at":"2024-09-24T19:41:24.747Z","updated_at":"2025-08-29T05:10:50.917Z","avatar_url":"https://github.com/nkristek.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ![Smaragd](./resources/logo-x32.png)\n\n[![CI Status](https://github.com/nkristek/Smaragd/workflows/CI/badge.svg)](https://github.com/nkristek/Smaragd/actions)\n[![NuGet version](https://img.shields.io/nuget/v/NKristek.Smaragd.svg)](https://www.nuget.org/packages/NKristek.Smaragd/)\n\nThis is a very lightweight library containing base classes for implementing .NET applications using the MVVM architecture.\nIt is fully unit tested and platform independent.\n\n## Features\n\nSmaragd offers base implementations of key .NET interfaces for building WPF / MVVM applications.\n\n![Core class diagram](./resources/diagram.png)\n\nIn addition, it enables developers to:\n\n- Build dialog and tree structures via [`DialogModel`](https://github.com/nkristek/Smaragd/wiki/DialogModel) and [`TreeViewModel`](https://github.com/nkristek/Smaragd/wiki/TreeViewModel)\n- Execute commands synchronously and asynchronously via [`ViewModelCommand`](https://github.com/nkristek/Smaragd/wiki/Commands) and [`AsyncViewModelCommand`](https://github.com/nkristek/Smaragd/wiki/Commands)\n- Perform validation via [`FuncValidation`](https://github.com/nkristek/Smaragd/blob/master/src/Smaragd/Validation/FuncValidation.cs) and [`PredicateValidation`](https://github.com/nkristek/Smaragd/blob/master/src/Smaragd/Validation/PredicateValidation.cs)\n- Manage state updates for interdependent properties via [`PropertySourceAttribute`](https://github.com/nkristek/Smaragd/wiki/ViewModel#propertysourceattribute)\n\nFor more information, please visit the [documentation](https://github.com/nkristek/Smaragd/wiki).\n\n## Installation\n\nThe recommended way to use this library is via [NuGet](https://www.nuget.org/packages/NKristek.Smaragd/).\n\nCurrently supported frameworks:\n- .NET Standard 2.0 or higher\n- .NET Framework 4.5 or higher\n\n## Quick Start\n\nThe following is a simple demonstration of some core features of Smaragd.\n\n1. Choose a base class for your **ViewModel**.\n\n   - Inherit from [`ViewModel`](https://github.com/nkristek/Smaragd/wiki/ViewModel) if you want to use the fill feature set (recommended)\n   - Inherit from [`Bindable`](https://github.com/nkristek/Smaragd/wiki/Bindable) if you only want an implementation of `INotifyPropertyChanged` and `INotifyPropertyChanging`\n\n    ```csharp\n    class AppViewModel : ViewModel\n    {\n        // ...\n    }\n    ```\n\n2. Add a property with a backing field that invokes `PropertyChanged` when set.\n\n    ```csharp\n    class AppViewModel : ViewModel\n    {\n            private string _name;\n            public string Name\n            {\n                get =\u003e _name;\n                set =\u003e SetProperty(ref _name, value);\n            }\n    }\n    ```\n\n3. Make the property dependent on the `ViewModel`'s `IsDirty` property. `IsDirty` indicates whether property values have changed. The `Name` property then automatically updates observing views when `IsDirty` changes.\n\n    ```csharp\n    class AppViewModel : ViewModel\n    {\n            private string _name;\n\n            [PropertySource(nameof(IsDirty))]\n            public string Name\n            {\n                get =\u003e IsDirty ? $\"{_name} (unsaved changes)\" : _name;\n                set =\u003e SetProperty(ref _name, value);\n            }\n    }\n    ```\n\n4. Add an async command to reset the `IsDirty` flag.\n\n    ```csharp\n    class AppViewModel : ViewModel\n    {\n        private string _name;\n\n        [PropertySource(nameof(IsDirty))]\n        public string Name\n        {\n            get =\u003e IsDirty ? $\"{_name} (unsaved changes)\" : _name;\n            set =\u003e SetProperty(ref _name, value);\n        }\n\n\n        private IViewModelCommand\u003cAppViewModel\u003e _saveCommand;\n\n        [IsDirtyIgnored]\n        [IsReadOnlyIgnored]\n        public IViewModelCommand\u003cAppViewModel\u003e SaveCommand =\u003e _saveCommand ??= new SaveCommand(this)\n    }\n\n\n    class SaveCommand : AsyncViewModelCommand\u003cAppViewModel\u003e\n    {\n        public SaveCommand(AppViewModel context)\n        {\n            Context = context;\n        }\n\n        protected override async Task ExecuteAsync(AppViewModel viewModel, object parameter)\n        {\n            // SaveChanges(viewModel);\n            viewModel.IsDirty = false;\n        }\n    }\n   ```\n\n5. Create a view in XAML for your `ViewModel` and enjoy working with bindings.\n\n    ```xml\n    \u003cWindow Title=\"{Binding Name}\"\u003e\n        \u003cButton Command=\"{Binding SaveCommand}\"\u003e\n    \u003c/Window\u003e\n    ```\n\nIn case you would like to see a more advanced reference application please don't hesitate to visit my other project [Stein](https://github.com/nkristek/Stein).\n\n## Why another MVVM library?\n\nThis library originated in my other project [Stein](https://github.com/nkristek/Stein) and was subsequently moved to its own repository and nuget package. The goal is to provide a great yet minimal foundation which also promotes a good code style. Nearly everything is marked virtual ([except events](https://msdn.microsoft.com/en-us/library/hy3sefw3.aspx)) so you can customize it to fit your needs.\n\nAnd of course, this library is [🚀blazing fast🚀](https://twitter.com/acdlite/status/974390255393505280).\n\n## Contribution\n\nIf you find a bug feel free to open an issue. Contributions are also appreciated.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnkristek%2Fsmaragd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnkristek%2Fsmaragd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnkristek%2Fsmaragd/lists"}