Common.Xamarin.ViewModel 1.1.2

.NET 5.0 .NET Standard 2.0
Install-Package Common.Xamarin.ViewModel -Version 1.1.2
dotnet add package Common.Xamarin.ViewModel --version 1.1.2
<PackageReference Include="Common.Xamarin.ViewModel" Version="1.1.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Common.Xamarin.ViewModel --version 1.1.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Common.Xamarin.ViewModel, 1.1.2"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install Common.Xamarin.ViewModel as a Cake Addin
#addin nuget:?package=Common.Xamarin.ViewModel&version=1.1.2

// Install Common.Xamarin.ViewModel as a Cake Tool
#tool nuget:?package=Common.Xamarin.ViewModel&version=1.1.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

Common.Xamarin.ViewModel

Common Xamarin ViewModel to Help with Property Relationships

Purpose

This library was created to eliminate some of the boilerplating that is needed to have a useful viewmodel in Xamarin (or WPF).

Basic Usage

Create a viewmodel that extends BaseViewModel to have access to the built in features of the library.

public class ExampleViewModel : Common.Xamarin.ViewModel {
	
	//Basic Examples
	public string Title { 
		get => GetValue<string>(); 
		set => SetValue(value); 
	}

	public int Count {
		get => GetValue<int>();
		set => SetValue(value);
	}
}

Extended Usage (Relationships)


using Common.Xamarin.ViewModel.Attributes;

//...

public class RelationshipViewModel : Common.Xamarin.ViewModel {
	//Basic Examples
	//This value affects IsValid
	public string Title { 
		get => GetValue<string>(); 
		set => SetValue(value); 
	}

	//This Value Affects both Message and IsValid
	[Affects(nameof(Message))]
	public int Count {
		get => GetValue<int>();
		set => SetValue(value);
	}

	[AffectedBy(nameof(Title), nameof(Count))]
	public bool IsValid => Count > 0 && !string.IsNullOrEmpty(Title);

	//This one could also be AffectedBy Count.
	public string Message => $"The total count is: {Count}";
}

ShellAware ViewModels * New *

Package:Common.Xamarin.ViewModel.ShellAware Shell Aware View Models simplify the process of navigating through shell as well as passing and receiving values between viewmodels. This is an extension of the common BaseViewModels but specifically for Xamarin.

ShellAwareViewModel:

Class that automates a lot of the process of transmitting information between viewmodels as navigation occurs. Initially I intended to extend the process allowed via QueryPropertyAttribute usage, but Xamarin already does some auto setting via this parameter which do not allow for complex data transmission. It extends BaseViewModel so the same utilities for getting and setting are still available. There are 2 attributes which simplify communication:

QueryParameterAttribute

These are examples of the usage of the parameters passed via query between shell viewmodels

    [QueryParameter("queryid")] //Receive value stored in shell parameter queryId
	 public string QueryId { get => GetValue<string>(); set => SetValue(value); }

    [QueryParameter] //Receive value stored in shell parameter of the same name as the property
     public int Id { get => GetValue<string>(); set => SetValue(value); }
NavigationParameterAttribute

These are examples of the usage. This attribute inherits from QueryParameterAttribute so it automatically populates the value on navigating to the viewmodel with this attribute, and will automatically populate the query on navigation. The parameters are the same as QueryParameterAttribute.

Automating Communication

The ShellAwareViewModel has a method GoToAsync that wraps around the Shell.Current.GoToAsync method, but adds the logic to serialize data transmitted between viewmodels.

   await GoToAsync("NewRoute"); //Will serialize any navigation properties into the Query
   await GoToAsync("NewRoute", new Dictionary<string, object> { 
                                   { "Test", 1 }
                               });

Additional

Triggers on Change

Technically you can implement triggers in a variety of ways including subscribing to the INotifyPropertyChanged Event, but that can usually be a little messy. Instead you can implement Method Calls in either the getter or the setter of the properties to handle if you want to manipulate the old or new data.

Example:

	///...
	public string Title { 
		get {
			var value = GetValue<string>();
			//Takes the newly stored value.  This getter is accessed on each Notified Change 
			//so it would execute after a change
			CallMethodWithNewValue(value); 
			return value;
		}
		set {
          //Optional if you need to compare the values or something along those lines
		  var oldValue = GetValue<string>(); 
		  //Called everytime there is a change in the value of this particular property.
		  CallMethodWithBothValues(oldValue, value);
		  SetValue(value); 
		}
	}

Implementing Events

If you want to enable the INavigationAware, IResetOnNavigation events than in the Class that extends your shell you can modify it like so:


    // Autogenerated code for Xamarin Forms Shell Navigation
    public partial class AppShell : Xamarin.Forms.Shell
    {
        public AppShell()
        {
            InitializeComponent();
            Routing.RegisterRoute(nameof(ItemDetailPage), typeof(ItemDetailPage));
            Routing.RegisterRoute(nameof(NewItemPage), typeof(NewItemPage));
        }

        private async void OnMenuItemClicked(object sender, EventArgs e)
        {
            await Current.GoToAsync("//LoginPage");
        }

        // ADD THE FOLLOWING CODE
        #region Common.Xamarin.ViewModel Extensions to Shell
        private Page _lastPage;

        protected override void OnNavigating(ShellNavigatingEventArgs args)
        {
            _lastPage = CurrentPage;
            base.OnNavigating(args);
        }

        protected override void OnNavigated(ShellNavigatedEventArgs args)
        {
            if (_lastPage?.BindingContext is IResetOnNavigation iR) iR.Reset();
            if (_lastPage?.BindingContext is INavigationAware iNA) iNA.OnNavigatedFrom();
            base.OnNavigated(args);
            if (CurrentPage?.BindingContext is INavigationAware NA) NA.OnNavigatedTo();
        }

        internal Page CurrentPage => 
             (Current?.CurrentItem?.CurrentItem as IShellSectionController)?.PresentedPage;
        #end region
    }
Product Versions
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows
.NET Core netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1
.NET Standard netstandard2.0 netstandard2.1
.NET Framework net461 net462 net463 net47 net471 net472 net48
MonoAndroid monoandroid
MonoMac monomac
MonoTouch monotouch
Tizen tizen40 tizen60
Xamarin.iOS xamarinios
Xamarin.Mac xamarinmac
Xamarin.TVOS xamarintvos
Xamarin.WatchOS xamarinwatchos
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.
  • .NETStandard 2.1

    • No dependencies.
  • net5.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Common.Xamarin.ViewModel:

Package Downloads
Common.Xamarin.ViewModel.ShellAware

Xamarin.Forms.Shell aware navigation to eliminate boilerplate code, allowing more complex transfer of data between viewmodels in navigation. Framework independent viewmodels that simplify logic.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.2 336 5/17/2021
1.1.1 165 5/17/2021
1.1.0 239 11/19/2020
1.0.5-DEV 276 11/19/2020
1.0.4-DEV 216 11/18/2020
1.0.3 783 6/5/2018
1.0.2 664 2/18/2018
1.0.1 704 12/29/2017
1.0.0 842 12/17/2017

- Small Bug Fix for Setting some values to null not triggering viewmodel changes.
- Fixed Nuget Project pointing to wrong github url.