user2114189
user2114189

Reputation: 450

Share ViewModel In Dotnet Maui Tabbed Page

I want to create a DotNet Maui App (Shell App) to let end user input the information. Since some entry pages contain many fields, I would like to split the whole data entry process to few screens. For example, the first screen "Tab1" used to input the general information and second screen "Tab2" input the details information and the last screen "Tab3" will input the general "Remarks". In Xamarin form I can use a TabbedPage (MainPage)to combine all three pages to 3 tabs then I create a ViewModel in MainPage and set the BindingContext of all tabs to that view model.

<TabbedPage ....>
    <Tab1 Title="Tab 1" x:Name="Tab1Page"/>
    <Tab2 Title="Tab 2" x:Name="Tab2Page"/>
    <Tab3 Title="Tab 3" x:Name="Tab3Page"/>
</TabbedPage>

// TabbedPage.cs

ViewModel model;

public TabbedPage() {
    InitializeComponent();
    model = new();
    Tab1Page.BindingContext = model;
    Tab2Page.BindingContext = model;
    Tab3Page.BindingContext = model;
}

However, from information of Microsoft, TabbedPage is not supported in Maui Shell App. I only can create a flyout tab page from Shell page to display three Tabs together but seems cannot share the view model on those three tabs. Is it any suggestions to solve my problem?

<Shell ....>
    <FlyoutItem Title="Data Input">
        <ShellContent ContentTemplate={DataTemplate Tab1}" Title="Tab1"/>
        <ShellContent ContentTemplate={DataTemplate Tab2}" Title="Tab2"/>
        <ShellContent ContentTemplate={DataTemplate Tab3}" Title="Tab3"/>
    </FlyoutItem>
</Shell>

Thanks

Upvotes: 0

Views: 2308

Answers (1)

Jessie Zhang -MSFT
Jessie Zhang -MSFT

Reputation: 13861

You can create a static global variable for the viewmodel in App.xaml.cs and access this variable in your different pages.

For example,we can first define a view model (TestViewModel.cs):

public class TestViewModel: INotifyPropertyChanged
{ 

    public TestViewModel() {

        str = "123";
    }

    public  string _str;

    public  string str
    {
        get
        {
            return _str;
        }
        set
        {
            _str = value;
            OnPropertyChanged("str");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

And define a static global variable in App.xaml.cs:

   public partial class App : Application
{

    public static TestViewModel testViewModel;
    public App()
    {
        InitializeComponent();

        MainPage = new AppShell();

        testViewModel = new TestViewModel();

    }
}

Then , you can assgin the global variable for BindingContext in different pages:

public partial class Tab1 : ContentPage
   {
    public Tab1()
    {
        InitializeComponent();

        BindingContext = App.testViewModel;

    }
   }



  public partial class Tab2 : ContentPage
{
    public Tab2()
    {
        InitializeComponent();

        BindingContext = App.testViewModel;

    }

    private void Button_Clicked(object sender, EventArgs e)
    {
        App.testViewModel.str = "2022/07/06";

    }
}

Upvotes: 1

Related Questions