Code Monkey home page Code Monkey logo

freshmvvm's Introduction

FreshMvvm.Maui

If you're looking for .NET MAUI version of FreshMvvm, aka FreshMvvm.Maui then please visit: https://github.com/XAM-Consulting/FreshMvvm.Maui

FreshMvvm for Xamarin.Forms

FreshMvvm is a super light Mvvm Framework designed specifically for Xamarin.Forms. It's designed to be Easy, Simple and Flexible.

How does it compare to other options?

  • It's super light and super simple
  • It's specifically designed for Xamarin.Forms
  • Designed to be easy to learn and develop (great when you are not ready for RxUI)
  • Uses a Convention over Configuration

Features

  • PageModel to PageModel Navigation
  • Automatic wiring of BindingContext
  • Automatic wiring of Page events (eg. appearing)
  • Basic methods (with values) on PageModel (init, reverseinit)
  • Built in IOC Container
  • PageModel Constructor Injection
  • Basic methods available in Model, like Alert
  • Built in Navigation types for SimpleNavigation, Tabbed and MasterDetail

Note Different to standard naming conventions, FreshMvvm uses Page and PageModel instead of View and ViewModel, this is inline with Xamarin.Forms using Pages Now we can use both the ViewModel naming conventions.

The Story

I (Michael Ridland) was part-way into a Xamarin Traditional application when Xamarin.Forms was released. I wanted to move the project onto Xamarin.Forms but on that project I was using MvvmCross. At that time MvvmCross had no support for Xamarin.Forms, so I had the option of 1) adapting MvvmCross, 2) finding an alternative or 3) rolling my own Mvvm. The best part about MvvmCross was it's two-way databinding to the native iOS/Android controls but since Xamarin.Forms already had the Databinding builtin, that wasn't useful and the size with MvvmCross was an overhead when I didn't require it. I also wasn't able to find an alternative that I could easily move to. So that I could keep it simple and flexible, I ended up rolling my own Mvvm.

It's grown up from this post on rolling your own Mvvm for Xamarin.Forms. I try hard to keep the simplicity of rolling your own Mvvm for Xamarin.Forms.

It was never a plan to create a framework but after presenting my Mvvm solution at a few events, I found many people wanted it and seemed to be really interested in it. Also considering I've been using this Framework in all my projects from the start of Xamarin.Forms I know that it works, so I created FreshMvvm and that's how it was born.

Conventions

This Framework, while simple, is also powerful and uses a Convention over Configuration style.

Note Different to standard naming conventions, FreshMvvm uses Page and PageModel instead of View and ViewModel, this is inline with Xamarin.Forms using Pages Now we can use both the ViewModel naming conventions.

  • A Page must have a corresponding PageModel, with naming important so a QuotePageModel must have a QuotePage The BindingContext on the page will be automatically set with the Model
  • A PageModel can have a Init method that takes a object
  • A PageModel can have a ReverseInit method that also take a object and is called when a model is poped with a object
  • PageModel can have dependancies automatically injected into the Constructor

Navigation

The Primary form of Navigation in FreshMvvm is PageModel to PageModel, this essentially means our views have no idea of Navigation.

So to Navigate between PageModels use:

await CoreMethods.PushPageModel<QuotePageModel>(); // Pushes navigation stack
await CoreMethods.PushPageModel<QuotePageModel>(null, true); // Pushes a Modal
await CoreMethods.PushPageModel<QuotePageModel> (pm => pm.Quote = "Quote 23") // Pushes Navigation Stack and initializes the property 'Quote' with  value 'Quote 23'

The engine for Navigation in FreshMvvm is done via a simple interface, with methods for Push and Pop. Essentially these methods can control the Navigation of the application in any way they like.

public interface IFreshNavigationService
{
	Task PushPage(Page page, FreshBasePageModel model, bool modal = false);
	Task PopPage(bool modal = false);
}

Within the PushPage and PopPage you can do any type of navigation that you like, this can be anything from a simple navigation to a advanced nested navigation.

The Framework contains some built in Navigation containers for the different types of Navigation.

Basic Navigation - Built In
var page = FreshPageModelResolver.ResolvePageModel<MainMenuPageModel> ();
var basicNavContainer = new FreshNavigationContainer (page);
MainPage = basicNavContainer;
Master Detail - Built In
var masterDetailNav = new FreshMasterDetailNavigationContainer ();
masterDetailNav.Init ("Menu");
masterDetailNav.AddPage<ContactListPageModel> ("Contacts", null);
masterDetailNav.AddPage<QuoteListPageModel> ("Pages", null);
MainPage = masterDetailNav;
Tabbed Navigation - Built In
var tabbedNavigation = new FreshTabbedNavigationContainer ();
tabbedNavigation.AddTab<ContactListPageModel> ("Contacts", null);
tabbedNavigation.AddTab<QuoteListPageModel> ("Pages", null);
MainPage = tabbedNavigation;
Implementing Custom Navigation

It's possible to setup any type of Navigation by implementing IFreshNavigationService.There's a sample of this in Sample Application named CustomImplementedNav.cs.

Sample Apps

  • Basic Navigation Sample
  • Tabbed Navigation Sample
  • MasterDetail Navigation Sample
  • Tabbed Navigation with MasterDetail Popover Sample (This is called the CustomImplementedNav in the Sample App)

Inversion of Control (IOC)

So that you don't need to include your own IOC container, FreshMvvm comes with a IOC container built in. It's using TinyIOC underneith, but with different naming to avoid conflicts.

To Register services in the container use Register:

FreshIOC.Container.Register<IDatabaseService, DatabaseService>();

To obtain a service use Resolve:

FreshIOC.Container.Resolve<IDatabaseService>();

*This is also what drives constructor injection.

IOC Container Lifetime Registration Options

We now support a fluent API for setting the object lifetime of object inside the IOC Container.

// By default we register concrete types as 
// multi-instance, and interfaces as singletons
FreshIOC.Container.Register<MyConcreteType>(); // Multi-instance
FreshIOC.Container.Register<IMyInterface, MyConcreteType>(); // Singleton 

// Fluent API allows us to change that behaviour
FreshIOC.Container.Register<MyConcreteType>().AsSingleton(); // Singleton
FreshIOC.Container.Register<IMyInterface, MyConcreteType>().AsMultiInstance(); // Multi-instance

As you can see below the IFreshIOC interface methods return the IRegisterOptions interface.

public interface IFreshIOC
{
    object Resolve(Type resolveType);
    IRegisterOptions Register<RegisterType>(RegisterType instance) where RegisterType : class;
    IRegisterOptions Register<RegisterType>(RegisterType instance, string name) where RegisterType : class;
    ResolveType Resolve<ResolveType>() where ResolveType : class;
    ResolveType Resolve<ResolveType>(string name) where ResolveType : class;
    IRegisterOptions Register<RegisterType, RegisterImplementation> ()
        where RegisterType : class
        where RegisterImplementation : class, RegisterType;
}

The interface that's returned from the register methods is IRegisterOptions.

public interface IRegisterOptions
{
    IRegisterOptions AsSingleton();
    IRegisterOptions AsMultiInstance();
    IRegisterOptions WithWeakReference();
    IRegisterOptions WithStrongReference();
    IRegisterOptions UsingConstructor<RegisterType>(Expression<Func<RegisterType>> constructor);
}

PageModel - Constructor Injection

When PageModels are pushed services that are in the IOC container can be pushed into the Constructor.

FreshIOC.Container.Register<IDatabaseService, DatabaseService>();

PageModel Important Methods

/// <summary>
/// The previous page model, that's automatically filled, on push
/// </summary>
public FreshBasePageModel PreviousPageModel { get; set; }

/// <summary>
/// A reference to the current page, that's automatically filled, on push
/// </summary>
public Page CurrentPage { get; set; }

/// <summary>
/// Core methods are basic built in methods for the App including Pushing, Pop and Alert
/// </summary>
public IPageModelCoreMethods CoreMethods { get; set; }    

/// <summary>
/// This method is called when a page is Pop'd, it also allows for data to be returned.
/// </summary>
/// <param name="returndData">This data that's returned from </param>
public virtual void ReverseInit(object returndData) { }

/// <summary>
/// This method is called when the PageModel is loaded, the initData is the data that's sent from pagemodel before
/// </summary>
/// <param name="initData">Data that's sent to this PageModel from the pusher</param>
public virtual void Init(object initData) { }

/// <summary>
/// This method is called when the view is disappearing. 
/// </summary>
protected virtual void ViewIsDisappearing (object sender, EventArgs e)
{
}

/// <summary>
/// This methods is called when the View is appearing
/// </summary>
protected virtual void ViewIsAppearing (object sender, EventArgs e)
{
}

The CoreMethods

Each PageModel has a property called 'CoreMethods' which is automatically filled when a PageModel is pushed, it's the basic functions that most apps need like Alerts, Pushing, Poping etc.

public interface IPageModelCoreMethods
{
	Task DisplayAlert (string title, string message, string cancel);
	Task<string> DisplayActionSheet (string title, string cancel, string destruction, params string[] buttons);
	Task<bool> DisplayAlert (string title, string message, string accept, string cancel);
	Task PushPageModel<T>(object data, bool modal = false) where T : FreshBasePageModel;
	Task PopPageModel(bool modal = false);
	Task PopPageModel(object data, bool modal = false);
	Task PushPageModel<T>() where T : FreshBasePageModel;
}

Page important methods

PageModel Init PropertyChanged

Sample PageModel

[ImplementPropertyChanged] // Use Fody for Property Changed Notifications
public class QuoteListPageModel : FreshBasePageModel
{
	IDatabaseService _databaseService;
	
	//These are automatically filled via Constructor Injection IOC
	public QuoteListPageModel (IDatabaseService databaseService) 
	{
		_databaseService = databaseService;
	}
	
	public ObservableCollection<Quote> Quotes { get; set; }
	
	public override void Init (object initData)
	{
		Quotes = new ObservableCollection<Quote> (_databaseService.GetQuotes ());
	}
	
	//The Framework support standard functions list appeaing and disappearing
	protected override void ViewIsAppearing (object sender, System.EventArgs e)
	{
		CoreMethods.DisplayAlert ("Page is appearing", "", "Ok");
		base.ViewIsAppearing (sender, e);
	}
	
	protected override void ViewIsDisappearing (object sender, System.EventArgs e)
	{
		base.ViewIsDisappearing (sender, e);
	}

	//This is called when a pushed Page returns to this Page
	public override void ReverseInit (object value)
	{
		var newContact = value as Quote;
		if (!Quotes.Contains (newContact)) {
			Quotes.Add (newContact);
		}
	}

	public Command AddQuote {
		get {
			return new Command (async () => {
				//Push A Page Model
				await CoreMethods.PushPageModel<QuotePageModel> ();
			});
		}
	}

	Quote _selectedQuote;

	public Quote SelectedQuote {
		get {
			return _selectedQuote;
		}
		set {
			_selectedQuote = value;
			if (value != null)
				QuoteSelected.Execute (value);
		}
	}

	public Command<Quote> QuoteSelected {
		get {
			return new Command<Quote> (async (quote) => {
				await CoreMethods.PushPageModel<QuotePageModel> (quote);
			});
		}
	}
}

Multiple Navigation Services

Itโ€™s always been possible to do any type of navigation in FreshMvvm, with custom or advanced scenarios were done by implementing a custom navigation service. Even with this ability people found it a little hard to do advanced navigation scenarios in FreshMvvm. After I reviewed all the support questions that came in for FreshMvvm I found that the basic issue people had was they wanted to be able to use our built in navigation containers multiple times, two primary examples are 1) within a master detail having a navigation stack in a master and another in the detail 2) The ability to push modally with a new navigation container. In order to support both these scenarios I concluded that the FreshMvvm required the ability to have named NavigationServices so that we could support multiple NavigationServiceโ€™s.

Using multiple navigation containers

Below weโ€™re running two navigation stacks, in a single MasterDetail.

var masterDetailsMultiple = new MasterDetailPage (); //generic master detail page

//we setup the first navigation container with ContactList
var contactListPage = FreshPageModelResolver.ResolvePageModel<ContactListPageModel> ();
contactListPage.Title = "Contact List";
//we setup the first navigation container with name MasterPageArea
var masterPageArea = new FreshNavigationContainer (contactListPage, "MasterPageArea");
masterPageArea.Title = "Menu";

masterDetailsMultiple.Master = masterPageArea; //set the first navigation container to the Master

//we setup the second navigation container with the QuoteList 
var quoteListPage = FreshPageModelResolver.ResolvePageModel<QuoteListPageModel> ();
quoteListPage.Title = "Quote List";
//we setup the second navigation container with name DetailPageArea
var detailPageArea = new FreshNavigationContainer (quoteListPage, "DetailPageArea");

masterDetailsMultiple.Detail = detailPageArea; //set the second navigation container to the Detail

MainPage = masterDetailsMultiple;

PushModally with new navigation stack

//push a basic page Modally
var page = FreshPageModelResolver.ResolvePageModel<MainMenuPageModel> ();
var basicNavContainer = new FreshNavigationContainer (page, "secondNavPage");
await CoreMethods.PushNewNavigationServiceModal(basicNavContainer, new FreshBasePageModel[] { page.GetModel() }); 

//push a tabbed page Modally
var tabbedNavigation = new FreshTabbedNavigationContainer ("secondNavPage");
tabbedNavigation.AddTab<ContactListPageModel> ("Contacts", "contacts.png", null);
tabbedNavigation.AddTab<QuoteListPageModel> ("Quotes", "document.png", null);
await CoreMethods.PushNewNavigationServiceModal(tabbedNavigation);

//push a master detail page Modally
var masterDetailNav = new FreshMasterDetailNavigationContainer ("secondNavPage");
masterDetailNav.Init ("Menu", "Menu.png");
masterDetailNav.AddPage<ContactListPageModel> ("Contacts", null);
masterDetailNav.AddPage<QuoteListPageModel> ("Quotes", null);
await CoreMethods.PushNewNavigationServiceModal(masterDetailNav);

Switching out NavigationStacks on the Xamarin.Forms MainPage

There's some cases in Xamarin.Forms you might want to run multiple navigation stacks. A good example of this is when you have a navigation stack for the authentication and a stack for the primary area of your application.

To begin with we can setup some names for our navigation containers.

public class NavigationContainerNames
{
    public const string AuthenticationContainer = "AuthenticationContainer";
    public const string MainContainer = "MainContainer";
}

Then we can create our two navigation containers and assign to the MainPage.

var loginPage = FreshMvvm.FreshPageModelResolver.ResolvePageModel<LoginViewModel>();
var loginContainer = new FreshNavigationContainer(loginPage, NavigationContainerNames.AuthenticationContainer);

var myPitchListViewContainer = new FreshTabbedNavigationContainer(NavigationContainerNames.MainContainer);

MainPage = loginContainer;

The Navigation Container will use the name passed as argument to register in this method

public FreshTabbedNavigationContainer(string navigationServiceName)
{
    NavigationServiceName = navigationServiceName;
    RegisterNavigation ();
}

protected void RegisterNavigation ()
{
    FreshIOC.Container.Register<IFreshNavigationService> (this, NavigationServiceName);
}

Once we've set this up we can now switch out our navigation containers.

CoreMethods.SwitchOutRootNavigation(NavigationContainerNames.MainContainer);

That name will be resolved in this method to find the correct Navigation Container

public void SwitchOutRootNavigation (string navigationServiceName)
{
    IFreshNavigationService rootNavigation = FreshIOC.Container.Resolve<IFreshNavigationService> (navigationServiceName);
}

Custom IOC Containers

The second major request for FreshMvvm 1.0 was to allow custom IOC containers. In the case that your application already has a container that you want to leverage.

Using a custom IOC container is very simple in that you only need to implement a single interface.

public interface IFreshIOC
{
    object Resolve(Type resolveType);
    void Register<RegisterType>(RegisterType instance) where RegisterType : class;
    void Register<RegisterType>(RegisterType instance, string name) where RegisterType : class;
    ResolveType Resolve<ResolveType>() where ResolveType : class;
    ResolveType Resolve<ResolveType>(string name) where ResolveType : class;
    void Register<RegisterType, RegisterImplementation> ()
        where RegisterType : class
        where RegisterImplementation : class, RegisterType;

And then set the IOC container in the System.

FreshIOC.OverrideContainer(myContainer);

Other Features/Tips

Customise Navigation Pages

Wondering how to customize the navigation bar in pages, eg control the NavigationPage that's created.

In some instances FreshMvvm creates container NavigationPage's for your sub pages. The NavigationContainer's have an override that allows you to control the creation of this NavigationPage. In the sample below we inherit from FreshTabbedNavigationContainer and override the CreateContainerPage and set the NavigationPage BarBackgroundColor to Blue.

using System;
using Xamarin.Forms;

namespace FreshMvvmApp
{
    public class NavigationBarCustom : FreshMvvm.FreshTabbedNavigationContainer
    {
        public NavigationBarCustom()
        {
        }

        protected override Page CreateContainerPage(Page page)
        {
            var container = new NavigationPage(page);

            container.BarBackgroundColor = Color.Blue;

            return container;
        }
    }
}

WhenAny

WhenAny is an extension method on INotifyPropertyChanged, it's a shorthand way to subscribe to a property changed event.

In the example below, we use any to link up

[PropertyChanged.AddINotifyPropertyChangedInterface]
public class ContactPageModel : FreshBasePageModel
{
    public ContactPageModel()
    {
        this.WhenAny(HandleContactChanged, o => o.Contact);
    }

    void HandleContactChanged(string propertyName)
    {
        //handle the property changed, nice
    }

    public Contact Contact { get; set; }
}

Related Videos/Quick Start Guides

FreshMvvm n=0 โ€“ Mvvm in Xamarin.Forms and Why FreshMvvm

FreshMvvm n=1 : Your first FreshMvvm Application

FreshMvvm n=2 โ€“ IOC and Constructor Injection

FreshMvvm n=3: Navigation in FreshMvvm

Implementing custom navigation in FreshMvvm for Xamarin.Forms

TDD in Xamarin Studio โ€“ Live Coding FreshMvvm

freshmvvm's People

Contributors

arctouch-douglaskazumi avatar asednev avatar asloth avatar bendiknesbo avatar cheesebaron avatar daniel-luberda avatar divikiranxam avatar dravela avatar foxanna avatar jakubjenis avatar kiliman avatar libin85 avatar masonyc avatar michaelxam avatar olexale avatar phdesign avatar pierceboggan avatar rid00z avatar wcoder avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

freshmvvm's Issues

Will there be a 0.0.7 version.

As the title says: will there be a 0.0.7 version or is there a 0.1.0/1.0 in the pipelines in several months from now? I know I can download the code as-is from github but using NuGet etc. gives me some more confidence in a version being stable etc.

Forms version

Not sure if this is a general Xamarin Forms question/problem but: FreshMvvm when got through nuget has been build with Forms 1.4.... We are currently at Forms 1.5.1. This seemed to be no problem until we started getting errors about 'xamlctask compilation'
I resolved this by removing the FreshMvvm nuget package, build the FreshMvvm dll's using the zip from nuget and referencing the resulting Dll's in my project.
Any comments?

full exception stack information

FreshMVVM is easy to use and supposed to speed up development time but actually more I use, I feel like it is my hump and it slows me down. everytime something is wrong on xaml or in viewmodel freshmvvm will popout this message. FreshTinyIoC.TinyIoCResolutionException: Unable to resolve type: blablaPage.xaml

I need to find the error debugging line by line if it is in xaml, i need to find out by removing things and try each label, button etc. Is there no possibility to enhance this situation with full exception information?

can't resolve type only in Release Build

I am unable to resolve a type in my Release configuration. The Debug work is functioning, but the Release only works if I remove the controls that have custom renderers.

The specific problem that I am having is a System.IO.FileNotFound exception on the namespace. The exception is being thrown when trying to PushModelAsync

Does MasterDetailContainer support menu item icons?

I was looking to derive from the FreshMasterDetailContainer to add menu item icons, but seem to be missing a few pieces. Does it have the ability to support this? Could you point me in the right direction?

My first thought was to override the AddPage() method but obviously I can't pass in any new parameters.

Update TinyIOC

I'm interested to know why TinyIOC is being included in the src but the namespace is just changed.

It would be better to just have TinyIOC as a nuget dependant. The version of TinyIOC included is outdated.

Asyncronous operations inside Init method

In this method I want to call to an asynchronous method to retrieve some data from server, but I see that this method is a void.

So, what is the recommended way to use the "await" operator here? Am I using the correct method?

Tab contents not showing when using XAML

Hi Michael,

I love my XAML so I tried to use FreshMvvm with a TabbedPage in XAML as well.
Mostly goes fine, but it won't show the actual content of the selected page. I'm probably doing something wrong, but I can't figure out what.

This is the XAML page I have.

<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Kilomeeter.Pages.MainPage" ItemsSource="{Binding Pages}">
  <TabbedPage.ItemTemplate>
    <DataTemplate>
      <Page Title="{Binding Title}" Icon="{Binding Icon}" />
    </DataTemplate>
  </TabbedPage.ItemTemplate>
</TabbedPage>

And this is my PageModel:

public class MainPageModel : FreshBasePageModel
    {
        public ObservableCollection<object> Pages { get; set; }

        public Page SelectedPage { get; set; }

        public MainPageModel()
        {
            Pages = new ObservableCollection<object>
            {
                FreshPageModelResolver.ResolvePageModel<CarsOverviewPageModel>(),
                FreshPageModelResolver.ResolvePageModel<MapPageModel>()
            };
        }
    }

Nothing fancy.
I've tried setting the SelectedPage and the CurrentPage on the TabbedPage but nothing seems to show up. Just the tabs, which are selectable, but an empty screen.

Any thoughts?

masterDetail doesnt display on all pages

Hi

I tried to create a masterdetail page using freshmvvm as below. but It looks like that it only display on start up page, when I navigate to any other page that is not the list of MasterPage, it will not be visible

 public App()
    {

        // The root page of your application
        LoadMasterDetail();
    }

public void LoadMasterDetail()
    {
        var masterDetailNav = new FreshMasterDetailNavigationContainer();
        masterDetailNav.Init("Menu", "Menu.png");
        masterDetailNav.AddPage<Page1PageModel>("Page1", null);
        masterDetailNav.AddPage<Page2PageModel>("Page2", null);
        masterDetailNav.AddPage<Page3PageModel>("Page3", null);
        MainPage = masterDetailNav;
    }

So according to above if I have page4Page and Page4PageModel which I am navigating through somewhere else when I am on this page, I dont see any masterdetail container. Is this supposed to be like that?

2nd thing, It executes through each and every pagemodel at the application start. This means if I have some heavy operation in any pageModel, this will reduce application start time. Is there anyway to prevent this?

thanks.

Invalid binding in XAML compiles, FreshTinyIoC gives vague error at app start

In a ContentPage named ThingListPage consisting of a Xaml file and code-behind, containing a ListView. For testing, I made an array of strings in the ContentPage's local ResourceDictionary and set it as the ListView's ItemsSource. Like this:

<ListViem ItemsSource="{Binding Source={StaticResource TestData}}">

Everything is fine. Later, I commented out the ResourceDictionary and its contents without changing the ListView's ItemSource. Xamarin continued to build and deploy without errors or warnings. Incidentally, the assembly-level attribute for Xaml compilation was enabled:

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]

Upon running the app, it gave a super-vague error on both iOS and Android emulators:

FreshTinyIoC.TinyIoCResolutionException: Unable to resolve type: MyApp.Pages.ThingListPage

I couldn't decipher anything from debugging in VS. It was only through trial-and-error that I found the problem came from the invalid binding statement.

Sorry for a less-than-definitive report, but I thought it better to report my notes thus far than to lose them to the great Notepad.exe in the sky.

FRESHMVVM MASTERDETAILPAGE EXECUTES VIEWMODELS

when you have FreshMasterDetailNavigationContainer as below, it will execute through each PageModel (ViewModel) init and constructor and if you have some initial data loading your view, this will be very expensive. Is there a way to prevent this? Otherwise for me Freshmvvm is no use.

thanks.

 var masterDetailNav = new FreshMasterDetailNavigationContainer();
        masterDetailNav.Init("Menu", "Menu.png");
        masterDetailNav.AddPage<page1PageModel>("page1", null);
        masterDetailNav.AddPage<page2PageModel>("page2", null);
         masterDetailNav.AddPage<page3PageModel>("page3", null);
        masterDetailNav.AddPage<page4PageModel>("page4", null);
        masterDetailNav.AddPage<page5PageModel>("page5", null);

Navigation from Master page

Hello,

I have a MenuPage (and MenuPageModel) as Master page. This menu has a list of options with some commands binded.

How can I do for do the navigation (PushAsync) from MenuPageModel? Here is my code.

        var menuPage = FreshPageModelResolver.ResolvePageModel<MenuPageModel>();
        this.Master = menuPage;

        var homePage = FreshPageModelResolver.ResolvePageModel<HomePageModel>();
        this.Detail = new FreshNavigationContainer(homePage);

Thanks.

Windows 10 Universal App Platform compatibility

I try to install FreshMvvm NuGet Package to Universal Windows project (with Xamarin.Forms 1.5.1.6466-pre2) and have the following errors:

FreshMvvm 0.0.6 is not compatible with UAP,Version=v10.0.
Some packages are not compatible with UAP,Version=v10.0.

Recommended way to bind page events to a page model - MessagingCenter?

I've been trying to understand the best way to bind events like Entry.Completed to logic in the page model, and conversely having the page model direct page control behavior like Entry.Focus().

It seems like a good solution for the Completed event is to wire the event(s) directly in the page code behind file, and in those events call MessagingCenter.Send() with a corresponding MessagingCenter.Subscribe() in the page model.

Then doing just the opposite to trigger Entry.Focus() in the page.

Is this pretty much best practice for things like this? Or is there a more binding-y way to do this?

Navigate to FreshTabbedNavigationContainer without pushing a modal

How can I navigate to a tabbed page without pushing a modal?

I am doing this:

var tabbedNavigation = new FreshTabbedNavigationContainer ("secondNavPage");
tabbedNavigation.AddTab<ContactListPageModel> ("Contacts", "contacts.png", null);
tabbedNavigation.AddTab<QuoteListPageModel> ("Quotes", "document.png", null);

await CoreMethods.PushNewNavigationServiceModal(tabbedNavigation);

But I don' want to navigate to this tabbed page in a Modal. Is this possible to do only push?

Thanks.

Proper cleanup of Pages

Hi,

I think there should be a way to clean up events and the releasing of the binding context when a page is popped.

I included a destructor in FreshBasePageModel

   ~FreshBasePageModel()
    {
        var page = CurrentPage;
        page.BindingContext = null;

        page.Appearing -= ViewIsAppearing;
        page.Disappearing -= ViewIsDisappearing;

    }

But I'm not sure if this would be enough as we don'r know when it will be called.
What do you think?

Cannot find PageModel

I been following your sample, using Xamarin Forms 2. It's not finding my LoginPageModel which is derived from FreshBasePageModel. I scrubbed through the sample app to see if I'm missing anything and I have what's needed.

Nested navigation inside a Modal does not work

CoreMethods.PushPageModel<T> does not navigate as expected in a Modal page.

Here is a video of the behavior: http://screencast.com/t/gErUL9c2h

The basic navigation wraps any new Modal in a NavigationPage, which is great. However, when trying to navigate to pages while that Modal is displayed, the pages are pushed underneath (in the other parent NavigationPage).

I have been playing with this and investigating my options. Suggestions are welcome.

Updating void Init() in FreshBasePageModel to async Task Init()

Updating void Init() to async Task Init() to support both testing and best practices. Current method is used async at times and this can cause issues with void return type.

I've created a branch with changes to this method but there are open questions. The change in FreshBasePageModel makes sense but results in a breaking change for all subclasses. Nothing major though, a small change.

The issue then comes from the ResolverPageModel calls calling Init(). They need to either, 1) be changed to async as well, as I did in the branch, or 2) the call needs to be wrapped in a Task.Run().

  1. This works and I already have the code working in the branch with updated sample code. The issue is that the ResolvePageModel call is now async which means the call to load this page can potentially get called twice by a handler if the user hits it more than once before the page resolves.

  2. The resolver wouldn't be able to ensure the page is initialized before it's displayed. This isn't terrible as this is pretty much how we are currently using the Init() method when there is an waited async call in the async void.

Branch with changes: https://github.com/BNoohi/FreshMvvm
@rid00z on issues with void Init(): http://www.michaelridland.com/xamarin/freshmvvm-n2-ioc-constructor-injection/ (also a great tutorial video)
MSDN article on async best practices: https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

Thoughts?

CoreMethods.PopToRoot not working in UWP

Calling await CoreMethods.PopToRoot(true/false) does nothing in UWP Project.
For the moment any workaround would be very appreciated.
Thx for your great work!

EDIT: I'm using FreshMvvm version 2.0.1 and Xamarin.Forms 2.1.0.6529
EDIT 2: Now, Xamarin Forms to 2.2.0.31 and FreshMvvm to 2.1.0, same problem

Master and Detail must be set before adding MasterDetailPage to a container

We have made no changes to our code but updating the newest (stable) Xamarin.Forms v2.1.0.6529 and FreshMVVM (1.0.3.003) we are now receiving this error:

Master and Detail must be set before adding MasterDetailPage to a container

I can confirm that Detail is not being set as the resolver can't find the PageModels.

Popping from outside of Page Model crashes

I am need to be able to pop a page and pop to root from outside of the page models. I am using the code from a different issue that lets you push pages from outside the model, but for some reason popping and popping to root do not work. Anyone have any ideas?

My code:

var navService = FreshMvvm.FreshIOC.Container.Resolve<IFreshNavigationService> (FreshMvvm.Constants.DefaultNavigationServiceName); 
await navService.PopPage();

I get the error:

'jobject' must not be IntPtr.Zero.
Parameter name: jobject

Doesn't support Light StatusBar on iOS

Currently there is no way to modify the BarTextColor of the NavigationPage object inside the navigation containers. In Xamarin.Forms in order to have a light status bar for iOS, the BarTextColor must be set to White.

Is there any chance this can be added? Not sure the best way to do so or I would make a pull request. In my test I added a boolean to CreateContainerPage

protected virtual Page CreateContainerPage(Page page, bool isLight = false)
    {
        var nav = new NavigationPage(page);
        if (isLight)
        {
            nav.BarTextColor = Color.White;
        }
        return nav;
    }

summary on the common component

Can you please do a little write up summarizing the common components \ features FreshMvvm has like navigation, property changed support, navigation, DI

Limited control over IOC Container registration lifetimes

According to TinyIOC documentation :

// By default we register concrete types as
// multi-instance, and interfaces as singletons
container.Register<MyConcreteType>(); // Multi-instance
container.Register<IMyInterface, MyConcreteType>(); // Singleton

This means the default implementation of registering concretes with interfaces in the IFreshIOC container is to register singletons which might not be the intended behavior, and there's not an easy way to change this without plugging in a brand new container implementation.

The TinyIOC convention of fluent extension methods wouldn't work here without exposing the underlying TinyIOC framework, so i would propose adding some extra methods and specifying the lifetime, making the Register<T, T2> multiinstance by default.

eg.

RegisterSingleton<RegisterType, RegisterImplementation>()
Register<RegisterType, RegisterImplementation>()

Enable/disable tabs in code?

I would like to be able to enable/disable one or more tabs (using tabbed navigation) based on certain conditions during run-ime. Is this possible (hiding/showing would be a good alternative).

Arc.Userdialogs

I'm using Arc.Userdialogs together with FreshMvvm which works well with one exception: the messages(toasts) appear and reappear as if there is an additional refresh/repaint by FreshMvvm.

Did you ever use Arc.Userdialogs with FreshMvvm and are there any gotchas or whatever?

Can't add tab without an icon

I get an "Argument null exception" error if I use null as the icon parameter in the FreshTabbedNavigationContainers, AddTab.

If I use whitespace, UIKit.UIImage gives me another error.

The example here uses "null", http://goo.gl/AvlBbO
Maybe it's a change in Xamarin that courses this issue?

Cant two pages have the same PageModel?

I have SearchItemsPage and ItemsLookupPage. I want that both of them use the same pagemodel (ItemsPageModel).

Is this possible to "jump" the framework convention for exceptional cases?

Thanks :).

Release notes?

I noticed several new releases last month, I like that! Are there any release notes to find out what got changed/fixed/added?

Navigation is not done when showing Alert in the Init() method

Hello.

When I try to show an alert from the PageModel's Init() method (if there is any exception I want to show any UI alert), not only the navigation to the page is not done, but the navigation is "broken" for the all the application (so I can't do push to anywhere).

    public override void Init(object initData)
    {
        base.Init(initData);
        ...
        UserDialogs.Instance.Alert("Message", "Message content", "Close");            
    }

I have already tried without the UserDialogs plugin, and the error persists:

    ((MasterPage)Application.Current.MainPage).DisplayAlert("Message", "Message content", "Close");

Is this a bug? Any workaround?

Waiting for your replies. Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.