TabbedPage with multiple Tabs with different View Models BindingContext

AvoirAvoir Member ✭✭

Hi

I am new to mobile app development so hopefully the following will make sense.

I have a page Projects with a ListView with the following code: -->

 async void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
    {
        var project = args.SelectedItem as Project;
        if (project == null)
            return;
        var projectTab = new ProjectTabsPage();
        projectTab.BindingContext = new ProjectTabsViewModel(project);
        await Navigation.PushAsync(projectTab) ;

        // Manually deselect item.
        ProjectsListView.SelectedItem = null;
    }

My ProjectTabsViewModel looks like this:-->

 public class ProjectTabsViewModel : BaseViewModel
{
    public ProjectDetailViewModel projectDetailViewModel { get; set; }
    public ProblemDetailViewModel problemDetailViewModel { get; set; }

    public ProjectTabsViewModel(Project project)
    {
        projectDetailViewModel = new ProjectDetailViewModel(project);
        problemDetailViewModel = new ProblemDetailViewModel(project.id);
    }
}

My ProjectTabsPage looks like this: -->

  <TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:d="http://xamarin.com/schemas/2014/forms/design"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:ToolA.Views;assembly=ToolA"
         Title="{Binding Title}"
         x:Class="ToolA.Views.ProjectTabsPage">
 <!--Pages can be added as references or inline-->
 <local:ProjectDetailPage Title="Project Details" BindingContext="{Binding projectDetailViewModel}"></local:ProjectDetailPage>
  <local:ProblemsPage Title="Problems" BindingContext="{Binding problemDetailViewModel}"></local:ProblemsPage>
  </TabbedPage>

And its c#: -->

 public partial class ProjectTabsPage : TabbedPage
 {
    public ProjectTabsPage()
    {
        InitializeComponent();
    }
 }

So when I go from Projects list page to the project details page (Tab 1), the page knows about its projectDetailViewModel. However, when I click on the Problems tab (tab 2), problemDetailViewModel is null even if it was set in ProjectTabsViewModel .

Any ideas what I am doing wrong? Or if I am approaching this the wrong way?

All I want to do is display the parent record details (project) under tab 1 and a list of child records (problems) under tab 2.

Thanks.

Answers

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    Can you privide your viewmodel about Tab2? If you want show the id, you should set the id like following format( public string id { get; set; }), and do not forget to set attribute to the public.

     class ProblemDetailViewModel : BaseViewModel
     {
        public string id { get; set; }
    
        public ProblemDetailViewModel(string id)
        {
            this.id = id;
        }
     }
    

    Why you use one ViewModel that contain two ViewModels? Then binding context in the different ContentPage.

    Why not exclain the two pages like these code. Then binding it in the diferent pages directly.

           <TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:d="http://xamarin.com/schemas/2014/forms/design"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:ToolA.Views;assembly=ToolA"
         Title="{Binding Title}"
         x:Class="ToolA.Views.ProjectTabsPage">
    
        <local:ProjectDetailPage Title="Project Details" /> 
         <local:ProblemsPage Title="Problems" />
    
       </TabbedPage>
    

    In the ProjectDetailPage,xml

         <StackLayout>
            <Label Text="{Binding project.Id}"
    
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="CenterAndExpand" />
        </StackLayout>
    

    ProjectDetailPage.xml.cs

        public ProjectDetailPage()
        {
            InitializeComponent();
            Item item =new Item();
            item.Id="002";
            BindingContext = new ProjectDetailViewModel(item);
        }
    

    ProjectDetailViewModel.cs

     public class ProjectDetailViewModel : BaseViewModel
    {
        public Item project { get; set; }
    
        public ProjectDetailViewModel(Item project)
        {
            this.project = project;
        }
    }
    

    In the ProblemsPage.xaml

       <StackLayout>
            <Label Text="{Binding id}"
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="CenterAndExpand" />
        </StackLayout>
    

    ProblemsPage.xaml.cs

        public ProblemsPage()
        {
            InitializeComponent();
            var item=new Item();
            item.Id = "003";
            BindingContext = new ProblemDetailViewModel(item.Id);
        }
    

    ProblemDetailViewModel.cs

      public class ProblemDetailViewModel : BaseViewModel
    {
        public string id { get; set; }
    
        public ProblemDetailViewModel(string id)
        {
            this.id = id;
        }
    }
    

    Here is running GIF.

Sign In or Register to comment.