Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/FreshMvvm/FreshAwaitCommand.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,67 @@
using System;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Input;

namespace FreshMvvm
{
public sealed class FreshAwaitCommand<T> : FreshAwaitCommand
{
public FreshAwaitCommand(Action<T, TaskCompletionSource<bool>> execute)
: base((o, tcs) =>
{
if (IsValidParameter(o))
{
execute((T)o, tcs);
}
})
{
if (execute == null)
{
throw new ArgumentNullException(nameof(execute));
}
}

public FreshAwaitCommand(Action<T, TaskCompletionSource<bool>> execute, Func<T, bool> canExecute)
: base((o, tcs) =>
{
if (IsValidParameter(o))
{
execute((T)o, tcs);
}
}, o => IsValidParameter(o) && canExecute((T)o))
{
if (execute == null)
{
throw new ArgumentNullException(nameof(execute));
}
if (canExecute == null)
{
throw new ArgumentNullException(nameof(canExecute));
}
}

private static bool IsValidParameter(object o)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change parameter name for obj or @object

{
if (o != null)
{
// The parameter isn't null, so we don't have to worry whether null is a valid option
return o is T;
}

var t = typeof(T);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change variable name for type


// The parameter is null. Is T Nullable?
if (Nullable.GetUnderlyingType(t) != null)
{
return true;
}

// Not a Nullable, if it's a value type then null is not valid
return !t.GetTypeInfo().IsValueType;
}
}

/// <summary>
/// FreshAwaitCommand is designed to avoid the double tap issue in Xamarin.Forms for Android,
/// in Xamarin.Forms it's a common issue that double taps on command would open the same window multiple times.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,123 +1,122 @@
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace FreshMvvm
{
public class FreshMasterDetailNavigationContainer : Xamarin.Forms.MasterDetailPage, IFreshNavigationService
{
List<Page> _pagesInner = new List<Page> ();
Dictionary<string, Page> _pages = new Dictionary<string, Page> ();
ContentPage _menuPage;
ObservableCollection<string> _pageNames = new ObservableCollection<string> ();
ListView _listView = new ListView ();
private ListView _listView = new ListView();

protected List<Page> PagesInner = new List<Page>();
protected ObservableCollection<string> PageNames = new ObservableCollection<string>();

public Dictionary<string, Page> Pages { get { return _pages; } }
protected ObservableCollection<string> PageNames { get { return _pageNames; } }
public Dictionary<string, Page> Pages = new Dictionary<string, Page>();

public FreshMasterDetailNavigationContainer () : this(Constants.DefaultNavigationServiceName)
{
public FreshMasterDetailNavigationContainer() : this(Constants.DefaultNavigationServiceName)
{
}

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

public void Init (string menuTitle, string menuIcon = null)
public void Init(string menuTitle, string menuIcon = null)
{
CreateMenuPage (menuTitle, menuIcon);
RegisterNavigation ();
CreateMenuPage(menuTitle, menuIcon);
RegisterNavigation();
}

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

public virtual void AddPage<T> (string title, object data = null) where T : FreshBasePageModel
public virtual void AddPage<T>(string title, object data = null) where T : FreshBasePageModel
{
var page = FreshPageModelResolver.ResolvePageModel<T> (data);
page.GetModel ().CurrentNavigationServiceName = NavigationServiceName;
_pagesInner.Add(page);
var navigationContainer = CreateContainerPage (page);
_pages.Add (title, navigationContainer);
_pageNames.Add (title);
if (_pages.Count == 1)
var page = FreshPageModelResolver.ResolvePageModel<T>(data);
page.GetModel().CurrentNavigationServiceName = NavigationServiceName;
PagesInner.Add(page);
var navigationContainer = CreateContainerPage(page);
Pages.Add(title, navigationContainer);
PageNames.Add(title);
if (Pages.Count == 1)
Detail = navigationContainer;
}
public virtual void AddPage(string modelName, string title, object data = null)

public virtual void AddPage(Type pageModel, string title, object data = null)
{
var pageModelType = Type.GetType(modelName);
var page = FreshPageModelResolver.ResolvePageModel(pageModelType, null);
var page = FreshPageModelResolver.ResolvePageModel(pageModel, data);
page.GetModel().CurrentNavigationServiceName = NavigationServiceName;
_pagesInner.Add(page);
PagesInner.Add(page);
var navigationContainer = CreateContainerPage(page);
_pages.Add(title, navigationContainer);
_pageNames.Add(title);
if (_pages.Count == 1)
Pages.Add(title, navigationContainer);
PageNames.Add(title);
if (Pages.Count == 1)
Detail = navigationContainer;
}

internal Page CreateContainerPageSafe (Page page)
internal Page CreateContainerPageSafe(Page page)
{
if (page is NavigationPage || page is MasterDetailPage || page is TabbedPage)
return page;

return CreateContainerPage(page);
}

protected virtual Page CreateContainerPage (Page page)
protected virtual Page CreateContainerPage(Page page)
{
return new NavigationPage (page);
return new NavigationPage(page);
}

protected virtual void CreateMenuPage (string menuPageTitle, string menuIcon = null)
protected virtual void CreateMenuPage(string menuPageTitle, string menuIcon = null)
{
_menuPage = new ContentPage ();
_menuPage.Title = menuPageTitle;

_listView.ItemsSource = _pageNames;

_listView.ItemSelected += (sender, args) => {
if (_pages.ContainsKey ((string)args.SelectedItem)) {
Detail = _pages [(string)args.SelectedItem];
var _menuPage = new ContentPage();
_menuPage.Title = menuPageTitle;

_listView.ItemsSource = PageNames;

_listView.ItemSelected += (sender, args) =>
{
if (Pages.ContainsKey((string)args.SelectedItem))
{
Detail = Pages[(string)args.SelectedItem];
}

IsPresented = false;
};

_menuPage.Content = _listView;

var navPage = new NavigationPage (_menuPage) { Title = "Menu" };
var navPage = new NavigationPage(_menuPage) { Title = "Menu" };

if (!string.IsNullOrEmpty (menuIcon))
if (!string.IsNullOrEmpty(menuIcon))
navPage.Icon = menuIcon;

Master = navPage;
}

public Task PushPage (Page page, FreshBasePageModel model, bool modal = false, bool animate = true)
public Task PushPage(Page page, FreshBasePageModel model, bool modal = false, bool animate = true)
{
if (modal)
return Navigation.PushModalAsync (CreateContainerPageSafe(page));
return (Detail as NavigationPage).PushAsync (page, animate); //TODO: make this better
}
return Navigation.PushModalAsync(CreateContainerPageSafe(page));
return (Detail as NavigationPage).PushAsync(page, animate); //TODO: make this better
}

public Task PopPage (bool modal = false, bool animate = true)
{
public Task PopPage(bool modal = false, bool animate = true)
{
if (modal)
return Navigation.PopModalAsync (animate);
return (Detail as NavigationPage).PopAsync (animate); //TODO: make this better
}
return Navigation.PopModalAsync(animate);
return (Detail as NavigationPage).PopAsync(animate); //TODO: make this better
}

public Task PopToRoot (bool animate = true)
public Task PopToRoot(bool animate = true)
{
return (Detail as NavigationPage).PopToRootAsync (animate);
return (Detail as NavigationPage).PopToRootAsync(animate);
}

public string NavigationServiceName { get; private set; }
Expand All @@ -128,7 +127,7 @@ public void NotifyChildrenPageWasPopped()
((NavigationPage)Master).NotifyAllChildrenPopped();
if (Master is IFreshNavigationService)
((IFreshNavigationService)Master).NotifyChildrenPageWasPopped();

foreach (var page in this.Pages.Values)
{
if (page is NavigationPage)
Expand All @@ -144,12 +143,11 @@ public void NotifyChildrenPageWasPopped()

public Task<FreshBasePageModel> SwitchSelectedRootPageModel<T>() where T : FreshBasePageModel
{
var tabIndex = _pagesInner.FindIndex(o => o.GetModel().GetType().FullName == typeof(T).FullName);
var tabIndex = PagesInner.FindIndex(o => o.GetModel().GetType().FullName == typeof(T).FullName);

_listView.SelectedItem = _pageNames[tabIndex];
_listView.SelectedItem = PageNames[tabIndex];

return Task.FromResult((Detail as NavigationPage).CurrentPage.GetModel());
}
}
}

}