{"id":13808061,"url":"https://github.com/klemmchr/MvvmBlazor","last_synced_at":"2025-05-14T02:31:12.237Z","repository":{"id":37998075,"uuid":"184928566","full_name":"klemmchr/MvvmBlazor","owner":"klemmchr","description":"A lightweight Blazor Mvvm Library","archived":true,"fork":false,"pushed_at":"2023-11-14T20:48:18.000Z","size":484,"stargazers_count":246,"open_issues_count":9,"forks_count":50,"subscribers_count":19,"default_branch":"master","last_synced_at":"2024-11-11T05:59:57.123Z","etag":null,"topics":["bindingsource","blazor","blazor-server","blazor-wasm","mvvm","mvvm-framework","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/klemmchr.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,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-05-04T18:04:55.000Z","updated_at":"2024-10-01T08:00:06.000Z","dependencies_parsed_at":"2024-04-10T05:38:33.185Z","dependency_job_id":"6ce7ee52-fbb0-4593-91ab-f3afaaff1e6b","html_url":"https://github.com/klemmchr/MvvmBlazor","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemmchr%2FMvvmBlazor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemmchr%2FMvvmBlazor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemmchr%2FMvvmBlazor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klemmchr%2FMvvmBlazor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/klemmchr","download_url":"https://codeload.github.com/klemmchr/MvvmBlazor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225273209,"owners_count":17448070,"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":["bindingsource","blazor","blazor-server","blazor-wasm","mvvm","mvvm-framework","viewmodel"],"created_at":"2024-08-04T01:01:34.394Z","updated_at":"2024-11-19T00:30:31.643Z","avatar_url":"https://github.com/klemmchr.png","language":"C#","funding_links":[],"categories":["Libraries \u0026 Extensions"],"sub_categories":["Tools \u0026 Utilities"],"readme":"MvvmBlazor\n================\n[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fchris579%2FMvvmBlazor%2Fbadge\u0026style=flat-square)](https://github.com/chris579/MvvmBlazor/actions) [![NuGet](https://img.shields.io/nuget/v/MvvmBlazor.svg?style=flat-square)](https://www.nuget.org/packages/MvvmBlazor) [![NuGet](https://img.shields.io/nuget/dt/MvvmBlazor)](https://www.nuget.org/packages/MvvmBlazor) \n\n\nMvvmBlazor is a small framework for building Blazor WebAssembly and Blazor Server apps. With its easy-to-use MVVM pattern you\ncan increase your development speed while minimising the effort required to make it work.\n\n## Getting started\n\nMvvmBlazor is available on [NuGet](https://www.nuget.org/packages/MvvmBlazor). You will need **.NET 6** to use this\nlibrary.\n\nThe library needs to be added to the DI container in order to use it. This is done in your `Startup` class.\n\n```c#\npublic class Startup\n{\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddMvvm();\n    }\n}\n```\n\n## Usage\n\n### Components\n\nComponents need to inherit the base class `MvvmBlazor.Components.MvvmComponentBase` if you want to inject your view\nmodel manually. You can set a binding on any view model you like to.\n\nIf you want full support use `MvvmBlazor.Components.MvvmComponentBase\u003cT\u003e` and specify your view model type as a generic\nargument.\nYour view model will get auto injected into the component and set as a binding context.\n\n#### BindingSource\n\nThe binding source is the default source object a binding will be made to. It is set automatically when using the base\nclass `MvvmBlazor.Components.MvvmComponentBase\u003cT\u003e` where `T` is your view model type. You can access it via\nthe `BindingContext` property in your component.\n\n#### Bindings\n\nBindings are achieved via the `Bind` method in the component. If the value of the bound property has changed the\ncomponent will be told to rerender automatically. In this example we assume that the class `ClockViewModel` has a\nproperty called `DateTime`.\n\n```c#\n@inherits MvvmComponentBase\u003cClockViewModel\u003e\n\nCurrent time: @Bind(x =\u003e x.DateTime)\n```\n\nBindings can also be done by specifying the binding source explicitly:\n\n```c#\n@inherits MvvmComponentBase\n@inject ClockViewModel ClockViewModel\n\nCurrent time: @Bind(ClockViewModel, x =\u003e x.DateTime)\n```\n\nBindings also handle background updating automatically. No need to invoke the main thread.\n\n#### Collection Bindings\n\nIf you want to have a collection that automatically notifies the component when it has changed you should use one that\nimplements `INotifyCollectionChanged`, e.g. `ObservableCollection\u003cT\u003e`.\n\nIn List scenarios you often chain view models to achieve bindings for every list element on it's corresponding view\nmodel. Given this view models\n\n```c#\nclass MainViewModel\n{\n    public ObservableCollection\u003cSubViewModel\u003e Items { get; }\n}\n\nclass SubViewModel\n{\n    private string _name;\n    public string Name\n    {\n        get =\u003e _name;\n        set =\u003e Set(ref, _name, value);\n    }\n}\n```\n\nyou can use bindings on your sub view models like this\n\n```c#\n@foreach (var item in Bind(x =\u003e x.Items))\n{\n    \u003clabel\u003e@Bind(item, x =\u003e x.Name)\u003c/label\u003e\n}\n```\n\nThis way the name of every list item is bound to it's corresponding entry in the view. If you change the name on any\nlist item, it will be changed in the view too.\n\n### EventHandlers\n\nEvent handles work just the way they work in blazor. When you use the non generic base class you can bind any injected\nobject on them.\n\n```c#\n@inherits MvvmComponentBase\n@inject CounterViewModel CounterViewModel\n\n\u003cbutton @onclick=\"@CounterViewModel.IncrementCount\"\u003eClick me\u003c/button\u003e\n```\n\nWhen using the generic base class you can directly bind them to your binding context.\n\n```c#\n@inherits MvvmComponentBase\u003cCounterViewModel\u003e\n\n\u003cbutton @onclick=\"@BindingContext.IncrementCount\"\u003eClick me\u003c/button\u003e\n```\n\n### ViewModel\n\nView models need to inherit the base class `MvvmBlazor.ViewModel.ViewModelBase`.\n\nIf you register a view model as scoped it will be tied to the lifetime of the component and disposed when the component is disposed.\nThis allows you to inject scoped services that should be short lived (e.g. a `DbContext`) without the need for using a factory.\n\nNote: Some services need to be resolved from the root service provider (e.g. `NavigationManager`). To do this you can access the root service provider via the `RootServiceProvider` property.\n\n#### Property implementation\n\nBindable properties need to raise the `PropertyChanged` event on the ViewModel.\n\nThe `Set`-Method is performing an equality check and is raising this event if needed. An example implementation could\nlook like this:\n\n```c#\nprivate int _currentCount;\npublic int CurrentCount\n{\n    get =\u003e _currentCount;\n    set =\u003e Set(ref _currentCount, value);\n}\n```\n\nAs an alternative you can leverage the power of source generators to do the tedious work for you.\nJust declare a private field inside of a view model and decorate if with the `Notify` attribute. The matching property will be auto generated for you.\n```c#\n[Notify]\nprivate int _currentCount;\n```\nNote: Some third party IDEs may not recognize source generators at the current point. They could report that the property does not exist while the project builds fine.\n\n#### Lifecycle methods\n\nView models have access to the same lifecycle methods as a component when they are set as a binding context. They are\ndocumented [here](https://docs.microsoft.com/en-us/aspnet/core/blazor/components?view=aspnetcore-3.0#lifecycle-methods).\n\n#### Parameters\n\nParameters are automatically populated to the view model. Declare a parameter in your component\n\n```c#\n@code {\n    [Parameter]\n    public string Name { get; set; }\n}\n```\n\nand declare the same parameter in your view model\n\n```c#\nclass ViewModel: ViewModelBase\n{\n    [Parameter]\n    public string Name { get; set; }\n}\n```\n\nCascading parameters are supported as well.\nThe parameter will be passed when parameters are set on the component. More information regarding the lifecycle can be\nfound in\nthe [Microsoft Documentation](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-6.0#lifecycle-events)\n.\n\n##### Type conversion\n\nWhen binding parameters in a component Blazor restricts you to a finite list of primitive types you can use. In some\nscenarios you might want to bind to a strong type and perform automatic conversions to it. A typical use case for this\nwould be a strongly typed identifier that you use in your application.\n\nView model parameters support type conversion\nusing [`TypeConverter`](https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.typeconverter?view=net-6.0).\nYour component parameters still needs to be a supported primitive type, however your view model parameter can be\nstrongly typed and will get auto converted. An example for this can be found in the TypedParameter sample.\n\n#### Dispose\n\nSince ViewModels are being injected through dependency injection in the scope of the component the\nDI [takes care](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-5.0#disposal-of-services)\nof disposing ViewModels.\n\n## Advanced scenarios\nSome libraries may force you to use a different base class than `MvvmComponentBase`.\nTo solve this issue you can create a custom mvvm component using source generators.\n\nCreate a partial class and decorate it with the `MvvmComponent` attribute.\n\n```c#\n[MvvmComponent]\npublic abstract partial class CustomComponentBase : UiLibraryComponentBase\n{\n\n}\n```\n\nAs a reference point see [`MvvmComponentBase`](https://github.com/klemmchr/MvvmBlazor/blob/master/src/MvvmBlazor.Core/Components/MvvmComponentBase.cs) and [`MvvmComponentBase\u003cT\u003e`](https://github.com/klemmchr/MvvmBlazor/blob/master/src/MvvmBlazor.Core/Components/MvvmComponentBaseT.cs).\nBoth are generated by a source generator as well.\n\n## Examples\n\nExamples for Blazor and Serverside Blazor can be\nfound [here](https://github.com/chris579/MvvmBlazor/tree/master/samples).\n\nYou will find several projects in there\n\n- *BlazorServersideSample*\n  A server for the blazor serverside sample\n- *BlazorClientsideSample.Server*\n  The server for the blazor clientside sample\n- *BlazorClientsideSample.Client*\n  The client for the blazor clientside sample\n\nThese projects act as wrapper projects for the main functionality that is shared among these examples.\n\n- *BlazorSample.Components*\n  The components and pages for the samples\n- *BlazorSample.ViewModels*\n  The view models for the pages\n- *BlazorSample.Domain*\n  Domain logic, stuff shared between components and view models\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklemmchr%2FMvvmBlazor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fklemmchr%2FMvvmBlazor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklemmchr%2FMvvmBlazor/lists"}