Search code examples
c#xamarin.formscastingtabbedpage

Calling one of child pages of TabbedPage to reach entry text


I know, "It is highly recommended to use MVVM" but I am just trying to understand and learn xamarin.forms structure. So here is the question: My application is based on TabbedPage which consists of two NavigationPage:

<TabbedPage.Children >
    <NavigationPage Title="Search">
        <NavigationPage.Icon>
            <OnPlatform x:TypeArguments="FileImageSource">
                <On Platform="iOS" Value="tab_feed.png"/>
            </OnPlatform>
        </NavigationPage.Icon>
        <x:Arguments>
            <views:SearchPage />                
        </x:Arguments>
    </NavigationPage>

    <NavigationPage Title="Study">
        <NavigationPage.Icon>
            <OnPlatform x:TypeArguments="FileImageSource">
                <On Platform="iOS" Value="tab_about.png"/>
            </OnPlatform>
        </NavigationPage.Icon>
        <x:Arguments> <!---->
            <views:AboutPage />
        </x:Arguments>
    </NavigationPage>
</TabbedPage.Children>

I am trying to call a child of this tabbedpage from a method created in a different class/view model to reach SearchBar text:

    public async void AddToList()
    {
        var mp = (MainPage)App.Current.MainPage;
        var sp = (SearchPage)mp.Children[0]; /// exception related with casting is thrown.
        var Word = sp.WordSearchBar.Text;
        ...
    }

SearchPage is defined as below. So I what is the issue creating casting exception. And how I can reach the searcbar text (other than bindings and MVVM)

public partial class SearchPage : ContentPage
{....}

Solution

  • mp.Children[0]; is kind of NavigationPage not SearchPage, so you get the casting exception.

    One way to achieve that is create a static property in the App class:

    public partial class `App` : Application
    {
        public static AboutPage aboutPageInstance { get; set; }
    
        public App()
        {
            InitializeComponent();
    
            DependencyService.Register<MockDataStore>();
            MainPage = new MainPage();
        }
    }
    

    Then assign the value in the AboutPage and let's say you have a label called currentLabel in the AboutPage:

    public partial class AboutPage : ContentPage
    {
        public Label currentLabel { get; set; }
    
        public AboutPage()
        {
            InitializeComponent();
    
            currentLabel = myLabel;
            App.aboutPageInstance = this;
        }
    }
    

    Then you can access the label in other ContentPage by:

    async void AddToList(object sender, EventArgs e)
    {
    
        if (App.aboutPageInstance != null)
        {
            AboutPage about = App.aboutPageInstance;
    
            about.currentLabel.Text = "kkk";
        }
    }
    

    MessagingCenter is also a good option to communicate between two different ContentPages.