Hey, quick question. Is it common practice to put Commands inside the ViewModel? I always inject the commands into the ViewModel, which meant that I had to expose the ShowViewModel<>(); inside as custom BaseViewModel.
It's a nice separation of concerns, but felt odd that I had to expose that method.
by doing that, I could do something like
public void Execute(object param)
{
var vm = (FooViewModel)param;
vm.ShowViewModel<BarViewModel>();
}
Not sure why you would Inject a Command? I don't see any reason at least if the code it is running is not platform specific, which it won't be, because ViewModels are defined in the PCL. Well at least what I do is keep the commands in the ViewModels.
I guess I like it for separation and testing. Just feels clean :S. Like I said, just wondering what the common practice is. I personally don't feel that ICommand is a ViewConcern, and I do reuse commands throughout the app. Each to their own.
humm common practice commands are on the view model, no need to injection, they are view related in terms of executing, but normally will need your view model to do stuff .. at least that's how i see it
0
AlecTucker.2208AUInsider, University, Developer Group Leadermod
Hi and thank you for this work.
As you told, WinPhone left, so I tryed to code this:
public class MvxFormsPhoneViewPresenter : IMvxPhoneViewPresenter
{
private PhoneApplicationFrame _rootFrame;
private NavigationPage _navigationPage;
public MvxFormsPhoneViewPresenter(PhoneApplicationFrame rootFrame)
{
_rootFrame = rootFrame;
}
public async void Show(MvxViewModelRequest request)
{
if (await TryShowPage(request))
return;
Mvx.Error("Skipping request for {0}", request.ViewModelType.Name);
}
private async Task<bool> TryShowPage(MvxViewModelRequest request)
{
var page = MvxPresenterHelpers.CreatePage(request);
if (page == null)
return false;
var viewModel = MvxPresenterHelpers.LoadViewModel(request);
if (_navigationPage == null)
{
Forms.Init();
_navigationPage = new NavigationPage(page);
// There is something to do here with _rootFrame and _navigationPage
// but don't know how to deal with
}
else
{
await _navigationPage.PushAsync(page);
}
page.BindingContext = viewModel;
return true;
}
public async void ChangePresentation(MvxPresentationHint hint)
{
if (hint is MvxClosePresentationHint)
{
// TODO - perhaps we should do more here... also async void is a boo boo
await _navigationPage.PopAsync();
}
}
}
First of all, I don't know if this is the good way to deal with Windows phone mvx presenters.
Also I think there something to do with _rootFrame and _navigationPage to make it work but don't how.
Jeremy, did you ever get this working? Im hoping to use be able to mix mvvmcross and x.f and I cant seem to get your code working. I dont get any errors but my view never shows. Not sure how to get the initial view to load correctly.
I have a view presenter for windows phone working. I'm sure it's not all baked but it at least does something. A caveat is that I'm ignoring the xamarin forms navigator and using the rootframe's navigation. You have to make an empty xaml file in the windows project for each of your views. It's just navigating to a blank view and then dropping content into it.
public class MvxFormsPhoneViewPresenter : IMvxPhoneViewPresenter
{
private PhoneApplicationFrame _rootFrame;
private MvxViewModelRequest _request;
public Stack<Type> TypeStack { get; set; }
public MvxFormsPhoneViewPresenter(PhoneApplicationFrame rootFrame)
{
TypeStack = new Stack<Type>();
_rootFrame = rootFrame;
_rootFrame.Source = new Uri("/MainPage.xaml", UriKind.Relative);
_rootFrame.Navigated += _rootFrame_Navigated;
_rootFrame.BackKeyPress += _rootFrame_BackKeyPress;
}
void _rootFrame_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
{
if (TypeStack.Count > 1)
{
TypeStack.Pop();
_request.ViewModelType = TypeStack.Pop();
}
}
void _rootFrame_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
var page = MvxPresenterHelpers.CreatePage(_request);
var viewModel = MvxPresenterHelpers.LoadViewModel(_request);
page.BindingContext = viewModel;
Forms.Init();
PhoneApplicationPage renderedPage = _rootFrame.Content as PhoneApplicationPage;
renderedPage.Content = page.ConvertPageToUIElement(renderedPage);
TypeStack.Push(_request.ViewModelType); }
public void Show(MvxViewModelRequest request)
{
_request = request;
if (TryShowPage(request))
return;
Mvx.Error("Skipping request for {0}", request.ViewModelType.Name);
}
private bool TryShowPage(MvxViewModelRequest request)
{
_rootFrame.Navigate(new Uri("/Views/" + request.ViewModelType.Name.Replace("ViewModel", "Page") + ".xaml", UriKind.Relative));
return true;
}
public void ChangePresentation(MvxPresentationHint hint)
{
if (hint is MvxClosePresentationHint)
{
// TODO - perhaps we should do more here... also async void is a boo boo
}
}
}
What I posted yesterday is silly. Please disregard it if you ever find this thread and use this. It's much better and you don't have to make a bunch of pointless windows xaml files. What I posted yesterday won't even work if you use a datepicker or something (how I learned). I'm just trying to figure this out too, forgive if I led you astray.
public class MvxFormsPhoneViewPresenter : IMvxPhoneViewPresenter
{
private PhoneApplicationFrame _rootFrame;
private NavigationPage _navigationPage;
private MvxViewModelRequest _request;
public MvxFormsPhoneViewPresenter(PhoneApplicationFrame rootFrame)
{
_rootFrame = rootFrame;
_rootFrame.Source = new Uri("/MainPage.xaml", UriKind.Relative);
_rootFrame.Navigated += _rootFrame_Navigated;
}
void _rootFrame_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
if (_navigationPage == null)
{
var page = MvxPresenterHelpers.CreatePage(_request);
Forms.Init();
_navigationPage = new NavigationPage(page);
PhoneApplicationPage renderedPage = _rootFrame.Content as PhoneApplicationPage;
renderedPage.Content = _navigationPage.ConvertPageToUIElement(renderedPage);
var viewModel = MvxPresenterHelpers.LoadViewModel(_request);
page.BindingContext = viewModel;
}
}
public async void Show(MvxViewModelRequest request)
{
_request = request;
if (await TryShowPage(request))
return;
Mvx.Error("Skipping request for {0}", request.ViewModelType.Name);
}
private async Task<bool> TryShowPage(MvxViewModelRequest request)
{
var page = MvxPresenterHelpers.CreatePage(_request);
if (page == null)
return false;
if (_navigationPage == null)
{
_rootFrame.Navigate(new Uri("/Views/someblankpage.xaml", UriKind.Relative));
}
else
{
await _navigationPage.PushAsync(page);
var viewModel = MvxPresenterHelpers.LoadViewModel(_request);
page.BindingContext = viewModel;
}
return true;
}
public void ChangePresentation(MvxPresentationHint hint)
{
if (hint is MvxClosePresentationHint)
{
// TODO - perhaps we should do more here... also async void is a boo boo
// and do something here for windows
}
}
}
I might take a look at consolidating the presenter stuff into a couple of nugets this weekend. Is it OK if I reuse some of your code, @SteveLynch ? You will get attributed for your contribution.
MvxFormsPhoneViewPresenter is not working i'm getting exception:
{Cirrious.CrossCore.Exceptions.MvxException: Unable to find incoming MvxViewModelRequest
at Cirrious.MvvmCross.WindowsPhone.Views.MvxPhoneViewsContainer.GetRequestFromXamlUri(Uri viewUri)
at Cirrious.MvvmCross.WindowsPhone.Views.MvxPhoneExtensionMethods.LoadViewModel(IMvxPhoneView phoneView, Uri navigationUri, IMvxBundle savedStateBundle)
at Cirrious.MvvmCross.WindowsPhone.Views.MvxPhoneExtensionMethods.<>c__DisplayClass1.b__0()
at Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate(IMvxView view, Func`1 viewModelLoader)
at Cirrious.MvvmCross.WindowsPhone.Views.MvxPhoneExtensionMethods.OnViewCreate(IMvxPhoneView phoneView, Uri navigationUri, IMvxBundle savedStateBundle)
at Cirrious.MvvmCross.WindowsPhone.Views.MvxPhonePage.OnNavigatedTo(NavigationEventArgs e)
at Microsoft.Phone.Controls.PhoneApplicationPage.InternalOnNavigatedTo(NavigationEventArgs e)
at Microsoft.Phone.Controls.PhoneApplicationPage.Microsoft.Phone.Controls.IPhoneApplicationPage.InternalOnNavigatedToX(NavigationEventArgs e)
at System.Windows.Navigation.NavigationService.RaiseNavigated(Object content, Uri uri, NavigationMode mode, Boolean isNavigationInitiator, IPhoneApplicationPage existingContentPage, IPhoneApplicationPage newContentPage)
at System.Windows.Navigation.NavigationService.CompleteNavigation(DependencyObject content, NavigationMode mode)
at System.Windows.Navigation.NavigationService.ContentLoader_BeginLoad_Callback(IAsyncResult result)}
Well, I finally decided to push on Nuget my customizations of Cheesebaron FormsPresenters work.
It's called MvxForms (formally MvvmCross- Xamarin Forms plugin) and its version 1.2.0-beta1 avaible on pre-release nuget channel allows you to work with MvvmCross & Xamarin.Forms on iOS, Android, Windows Phone Silverlight, Windows 8.1 and Windows Phone 8.1 thanks to last Xamarin Forms pre version packages.
. Blog post explaining use here.
. Nuget description here.
. GitHub repository here.
Nothing commercial here, only personal work shared, so feel free to fork and improve project on GitHub.
Also working on a Ninja Coder implementation that should come soon.
Posts
Thanks!
Note the WinPhone project does nothing right now. When I have time I will make a presenter for that as well.
Hey, quick question. Is it common practice to put Commands inside the ViewModel? I always inject the commands into the ViewModel, which meant that I had to expose the
ShowViewModel<>();
inside as custom BaseViewModel.It's a nice separation of concerns, but felt odd that I had to expose that method.
by doing that, I could do something like
Not sure why you would Inject a Command? I don't see any reason at least if the code it is running is not platform specific, which it won't be, because ViewModels are defined in the PCL. Well at least what I do is keep the commands in the ViewModels.
I guess I like it for separation and testing. Just feels clean :S. Like I said, just wondering what the common practice is. I personally don't feel that ICommand is a ViewConcern, and I do reuse commands throughout the app. Each to their own.
humm common practice commands are on the view model, no need to injection, they are view related in terms of executing, but normally will need your view model to do stuff .. at least that's how i see it
Nice work Tomasz
Hi and thank you for this work.
As you told, WinPhone left, so I tryed to code this:
First of all, I don't know if this is the good way to deal with Windows phone mvx presenters.
Also I think there something to do with _rootFrame and _navigationPage to make it work but don't how.
Maybe you can help to finish...
Thanks.
Jeremy, did you ever get this working? Im hoping to use be able to mix mvvmcross and x.f and I cant seem to get your code working. I dont get any errors but my view never shows. Not sure how to get the initial view to load correctly.
I have a view presenter for windows phone working. I'm sure it's not all baked but it at least does something. A caveat is that I'm ignoring the xamarin forms navigator and using the rootframe's navigation. You have to make an empty xaml file in the windows project for each of your views. It's just navigating to a blank view and then dropping content into it.
What I posted yesterday is silly. Please disregard it if you ever find this thread and use this. It's much better and you don't have to make a bunch of pointless windows xaml files. What I posted yesterday won't even work if you use a datepicker or something (how I learned). I'm just trying to figure this out too, forgive if I led you astray.
I might take a look at consolidating the presenter stuff into a couple of nugets this weekend. Is it OK if I reuse some of your code, @SteveLynch ? You will get attributed for your contribution.
Hi Tomasz
Did you actually package the Windows Phone View Presenter into Nuget? If so do you have it's name so I can give it a try please?
MvxFormsPhoneViewPresenter is not working i'm getting exception:
{Cirrious.CrossCore.Exceptions.MvxException: Unable to find incoming MvxViewModelRequest
at Cirrious.MvvmCross.WindowsPhone.Views.MvxPhoneViewsContainer.GetRequestFromXamlUri(Uri viewUri)
at Cirrious.MvvmCross.WindowsPhone.Views.MvxPhoneExtensionMethods.LoadViewModel(IMvxPhoneView phoneView, Uri navigationUri, IMvxBundle savedStateBundle)
at Cirrious.MvvmCross.WindowsPhone.Views.MvxPhoneExtensionMethods.<>c__DisplayClass1.b__0()
at Cirrious.MvvmCross.Views.MvxViewExtensionMethods.OnViewCreate(IMvxView view, Func`1 viewModelLoader)
at Cirrious.MvvmCross.WindowsPhone.Views.MvxPhoneExtensionMethods.OnViewCreate(IMvxPhoneView phoneView, Uri navigationUri, IMvxBundle savedStateBundle)
at Cirrious.MvvmCross.WindowsPhone.Views.MvxPhonePage.OnNavigatedTo(NavigationEventArgs e)
at Microsoft.Phone.Controls.PhoneApplicationPage.InternalOnNavigatedTo(NavigationEventArgs e)
at Microsoft.Phone.Controls.PhoneApplicationPage.Microsoft.Phone.Controls.IPhoneApplicationPage.InternalOnNavigatedToX(NavigationEventArgs e)
at System.Windows.Navigation.NavigationService.RaiseNavigated(Object content, Uri uri, NavigationMode mode, Boolean isNavigationInitiator, IPhoneApplicationPage existingContentPage, IPhoneApplicationPage newContentPage)
at System.Windows.Navigation.NavigationService.CompleteNavigation(DependencyObject content, NavigationMode mode)
at System.Windows.Navigation.NavigationService.ContentLoader_BeginLoad_Callback(IAsyncResult result)}
Well, I finally decided to push on Nuget my customizations of Cheesebaron FormsPresenters work.
It's called MvxForms (formally MvvmCross- Xamarin Forms plugin) and its version 1.2.0-beta1 avaible on pre-release nuget channel allows you to work with MvvmCross & Xamarin.Forms on iOS, Android, Windows Phone Silverlight, Windows 8.1 and Windows Phone 8.1 thanks to last Xamarin Forms pre version packages.
. Blog post explaining use here.
. Nuget description here.
. GitHub repository here.
Nothing commercial here, only personal work shared, so feel free to fork and improve project on GitHub.
Also working on a Ninja Coder implementation that should come soon.
@JeremyBRUN-PICARD Official support for Xamarin.Forms is now available in MvvmCross: https://github.com/MvvmCross/MvvmCross-Forms
You are more then welcome to make a PR for any fixes you might have to that repo!