简体   繁体   中英

How to pass data when navigating through TabBar?

To pass data beetwen viewmodels when navigating I use query parameters (IQueryAttributable), ie:

NavigationParameters[nameof(SomeProperty)] = SomeProperty;
await Shell.Current.GoToAsync("SomePage", NavigationParameters);

It works as it should be working, but I wish to put SomePage into a TabBar:

<TabBar>
    <ShellContent Route="SomePage"
        ContentTemplate="{DataTemplate local:SomePage}"/>
    ...
</TabBar>

Is there a way to pass data when user click/tap SomePage icon on the tab bar? Is there some event for that so I could hook up GoToAsync method? Or maybe there is another way than query to pass data beetwen viewmodels?

"You could also hold handles to other view models in your view model, like a common section that's shared between all your pages."

That is the advice to follow.

Suppose each tab's viewmodel has public MySharedType Shared { get; private set; } public MySharedType Shared { get; private set; } public MySharedType Shared { get; private set; } ,
and constructor is MyTab1ViewModel(MySharedType shared) { this.Shared = shared; } MyTab1ViewModel(MySharedType shared) { this.Shared = shared; } .

Then from xaml, access a shared property by: {Binding Shared.MyProperty1} .

If the two pages are in the same Tab ,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 (eg 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 = "Test";

    }
}

MauiProgram.cs:

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder.UseMauiApp<App>();
        builder.Services
            .AddSingleton<Page_1>
            .AddSingleton<ViewModel_1>
            .AddSingleton<Page_2>
            .AddSingleton<ViewModel_2>
            .AddSingleton<ISharedDataInterface, SharedDataInterfaceImplementanion>();
        return builder.Build();
    }
}

Page_1.xaml.cs:

public partial class Page_1 : ContentPage
{
    public LogoPage(ViewModel_1 viewModel_1)
    {
        BindingContext = viewModel_1;

        InitializeComponent();
    }
}

Page_2.xaml.cs:

public partial class Page_2 : ContentPage
{
    public LogoPage(ViewModel_2 viewModel_2)
    {
        BindingContext = viewModel_2;

        InitializeComponent();
    }
}

ViewModel_1.cs:

public class ViewModel_1
{
    public ViewModel_1(ISharedDataInterface sharedDataInterfaceImplementanion)
    {
        ...
    }
}

ViewModel_2.cs:

public class ViewModel_2
{
    public ViewModel_2(ISharedDataInterface sharedDataInterfaceImplementanion)
    {
        ...
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM