标签中的嵌套视图绑定到单独的ViewModel

时间:2018-08-02 08:36:47

标签: data-binding xamarin.forms mvvmcross

有没有办法提供一个嵌套视图,它是自己的viewmodel?

示例: TabbedView类型的主视图具有多个选项卡。

<mvx:MvxTabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
                     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                     x:Class="Foo.Core.Pages.Access.MainPage"
                     xmlns:res="clr-namespace:Foo.Core.Resources;assembly=Foo.Core"
                     xmlns:mvx="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
                     xmlns:views="clr-namespace:Foo.Core.Pages.Access">

    <TabbedPage.Children>
        <views:LoginPage></views:LoginPage>
        <views:RegisterPage></views:RegisterPage>
    </TabbedPage.Children>
</mvx:MvxTabbedPage>

LoginPageRegisterPage位于不同的视图中。但是所有绑定必须在MainViewModel中,并且我希望绑定分别在LoginViewModelRegisterViewModel中。

有没有一种方法来设置属性绑定到适当的viewmodel?最好在XAML中使用。

1 个答案:

答案 0 :(得分:0)

要使其正常工作,您需要让NavigationService(并因此Presenter)加载子页面:

Xamarin.Forms View Presenter -> MvxTabbedPagePresentationAttribute

您的情况应该是这样的:

ViewModels

public class MyTabsContainerViewModel : MvxViewModel
{
    private readonly IMvxNavigationService _navigationService;

    public MyTabsContainerViewModel(IMvxNavigationService navigationService)
    {
        _navigationService = navigationService ?? throw new ArgumentNullException(nameof(navigationService));
    }


    public override async void ViewAppearing()
    {
        await ShowInitialViewModels();
        base.ViewAppearing();
    }

    private async Task ShowInitialViewModels()
    {
        var tasks = new List<Task>();
        tasks.Add(_navigationService.Navigate<LoginViewModel>());
        tasks.Add(_navigationService.Navigate<RegisterViewModel>());
        await Task.WhenAll(tasks);
    }
}

public class LoginViewModel : MvxViewModel
{
}

public class RegisterViewModel : MvxViewModel
{
}

观看次数

MyTabsContainerPage.xaml

<?xml version="1.0" encoding="utf-8"?>
<views:MvxTabbedPage x:TypeArguments="viewModels:MyTabsContainerViewModel" xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewModels="clr-namespace:Foo.Core.ViewModels;assembly=Foo.Core"
             xmlns:views="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
             x:Class="Foo.Core.Pages.Access.MyTabsContainerPage">

</views:MvxTabbedPage>

MyTabsContainerPage.xaml.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
[MvxMasterDetailPagePresentation(Position = MasterDetailPosition.Detail, NoHistory = true)]
public partial class MyTabsContainerPage : MvxTabbedPage<MyTabsContainerViewModel>
{
    public MyTabsContainerPage()
    {
        InitializeComponent();
    }
}

LoginPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<views:MvxContentPage x:TypeArguments="viewModels:LoginViewModel" xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewModels="clr-namespace:Foo.Core.ViewModels;assembly=Foo.Core"
             xmlns:views="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
             x:Class="Foo.Core.Pages.Access.MixedNavTab1Page">

        <StackLayout>
            <Label Text="This is Tab 1" />
        </StackLayout>

</views:MvxContentPage>

LoginPage.xaml.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
[MvxTabbedPagePresentation(WrapInNavigationPage = false, Title = "LoginTab1")]
public partial class LoginPage : MvxContentPage<LoginViewModel>
{
    public LoginPage()
    {
        InitializeComponent();
    }
}

RegisterPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<views:MvxContentPage x:TypeArguments="viewModels:RegisterViewModel" xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:viewModels="clr-namespace:Foo.Core.ViewModels;assembly=Foo.Core"
             xmlns:views="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
             x:Class="Foo.Core.Pages.Access.RegisterPage">

        <StackLayout>
            <Label Text="This is Tab 2" />
        </StackLayout>

</views:MvxContentPage>

RegisterPage.xaml.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
[MvxTabbedPagePresentation(WrapInNavigationPage = false, Title = "RegisterTab2")]
public partial class RegisterPage : MvxContentPage<RegisterViewModel>
{
    public RegisterPage()
    {
        InitializeComponent();
    }
}

Playground project中的完整示例 HIH