Forum Xamarin Xamarin.Forms

Xamarin.Forms + MvvmCross

CheesebaronCheesebaron DKInsider, University mod

I have made a repository with a small sample of one way to use Xamarin.Forms with MvvmCross. You can find it here:
https://github.com/Cheesebaron/Xam.Forms.Mvx

Posts

  • ChaseFlorellChaseFlorell CAInsider, University mod

    Thanks!

  • CheesebaronCheesebaron DKInsider, University mod

    Note the WinPhone project does nothing right now. When I have time I will make a presenter for that as well.

  • ChaseFlorellChaseFlorell CAInsider, University mod
    edited June 2014

    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>();
    }
    
  • CheesebaronCheesebaron DKInsider, University mod

    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.

  • ChaseFlorellChaseFlorell CAInsider, University mod

    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.

  • rmarinhormarinho PTMember, Insider, Beta Xamurai

    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 :)

  • AlecTucker.2208AlecTucker.2208 AUInsider, University, Developer Group Leader mod

    Nice work Tomasz

  • JeremyBPJeremyBP FRMember ✭✭

    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.

    Maybe you can help to finish...

    Thanks.

  • JasonMichasJasonMichas USMember ✭✭

    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.

  • SteveLynchSteveLynch USMember

    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
    
                }
            }
        }
    
  • SteveLynchSteveLynch USMember

    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
    
            }
        }
    }
    
  • CheesebaronCheesebaron DKInsider, University mod
    edited September 2014

    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.

  • PeterDuerdenPeterDuerden USMember

    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? :)

  • AgtrixAgtrixAgtrixAgtrix AUMember ✭✭

    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)}

  • JeremyBPJeremyBP FRMember ✭✭

    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.

  • Martijn00Martijn00 NLInsider, University ✭✭✭

    @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!

Sign In or Register to comment.