subKiller
subKiller

Reputation: 168

Bind Two Different Views for same ViewModel

This looks like similar to MVVMCross - Bind the same ViewModel to 2 different Views

But after there I don't get an answer how can I select one View for ViewModel and in another time the second View for the same ViewModel.

As an example, I wanna have one ViewModel - LoginViewModel and two Views: PhoneLoginPage & TabletLoginPage.

According to information from Xamarin.Forms.Device.Idiom when it's a Phone I want to show PhoneLoginPage but when it's a Tablet - TabletLoginPage but have the same LoginViewModel binded to them.

How can I achieve it correctly? Mean, without any dirty tricks...

Thanks

Upvotes: 1

Views: 915

Answers (2)

subKiller
subKiller

Reputation: 168

With MvvmCross this is not possible, in runtime, we will get an Exception if we create two Views for the same ViewModel.

My solution was next:

<ProjectFolder>
    => Pages
        => Mobile
            XMobilePage.xaml
            YMobilePage.xaml
        => Tablets
            XTabletPage.xaml
            YTabletPage.xaml
    => PageModels
        => Mobile
            XMobilePageModel.cs
            YMobilePageModel.cs
        => Tablets
            XTabletPageModel.cs
            YTabletPageModel.cs

class XMobilePage: MvxContentPage<XMobilePageModel> {...}

class XTabletPage: MvxContentPage<XTabletPageModel> {...}

abstract SharedXPageModel
{
    //All Shared Commands and Comand Logic and other shared initialization
    abstract Task NavigateToYPageModel();
}

class XMobilePageModel : SharedXPageModel
{
    Task NavigateToYPageModel() => _mvxNavigationService.Navigate<YMobilePageModel>();
}

class XTabletPageModel : SharedXPageModel
{
    Task NavigateToYPageModel() => _mvxNavigationService.Navigate<YTabletPageModel>();
}

Upvotes: 0

Michal Diviš
Michal Diviš

Reputation: 2206

NOTE: I'm also on the side of having only one page.

But here's how I'd go about having two pages:

In case you're using some kind of a navigation service:

Just register different pages on app startup based on the device's idiom.

Along the lines of:

if(Device.Idiom == TargetIdiom.Tablet)
{
    SomeNavigationService.Register<LoginViewModel, TabletLoginPage>();
}
else
{
    SomeNavigationService.Register<LoginViewModel, PhoneLoginPage>();
}

In case you're doing the navigation in the page code-behind

Choose the page based on the device's idiom there...

if(Device.Idiom == TargetIdiom.Tablet)
{
    await Navigation.PushAsync(new TabletLoginPage(viewModel));
}
else
{
    await Navigation.PushAsync(new PhoneLoginPage(viewModel));
}

Upvotes: 2

Related Questions