Menu Item not showing in Xamarin.Forms after navigation back

Viewed 1540

I'm developing a Xamarin.Forms Android-App where on a ContentPage a CustomRenderer is being used to display a SearchView in the Header of the Page. The CustomRenderer for the "SearchPage" class looks like the following:

 /// <summary>
///     The search page renderer.
/// </summary>
public class SearchPageRenderer : PageRenderer
{
    /// <summary>
    ///     Gets or sets the search view.
    /// </summary>
    private SearchView searchView;

    /// <summary>
    ///     Gets or sets the toolbar.
    /// </summary>
    private Toolbar toolbar;

    /// <summary>
    ///     Reaction on the disposing of the page.
    /// </summary>
    /// <param name="disposing">A value indicating whether disposing.</param>
    protected override void Dispose(bool disposing)
    {
        if (this.searchView != null)
        {
            this.searchView.QueryTextChange -= this.OnQueryTextChangeSearchView;
        }

        this.toolbar?.Menu?.RemoveItem(Resource.Menu.mainmenu);
        base.Dispose(disposing);
    }

    /// <summary>
    ///     Reaction on the element changed event.
    /// </summary>
    /// <param name="e">The event argument.</param>
    protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
    {
        base.OnElementChanged(e);

        if (e?.NewElement == null || e.OldElement != null)
        {
            return;
        }

        this.AddSearchToToolBar();
    }

    /// <summary>
    ///     Adds a search item to the toolbar.
    /// </summary>
    private void AddSearchToToolBar()
    {
        this.toolbar = (CrossCurrentActivity.Current?.Activity as MainActivity)?.FindViewById<Toolbar>(Resource.Id.toolbar);

        if (this.toolbar != null)
        {
            this.toolbar.Title = this.Element.Title;
            this.toolbar.InflateMenu(Resource.Menu.mainmenu);

            this.searchView = this.toolbar.Menu?.FindItem(Resource.Id.action_search)?.ActionView?.JavaCast<SearchView>();

            if (this.searchView != null)
            {
                this.searchView.QueryTextChange += this.OnQueryTextChangeSearchView;
                this.searchView.ImeOptions = (int)ImeAction.Search;
                this.searchView.MaxWidth = int.MaxValue;
                this.searchView.SetBackgroundResource(Resource.Drawable.textfield_search_holo_light);
            }
        }
    }

    /// <summary>
    ///     Reaction on the text change event of the searchbar.
    /// </summary>
    /// <param name="sender">The event sender.</param>
    /// <param name="e">The event argument.</param>
    private void OnQueryTextChangeSearchView(object sender, SearchView.QueryTextChangeEventArgs e)
    {
        var searchPage = this.Element as SearchPage;
        searchPage?.SearchCommand?.Execute(e?.NewText);
    }
}

Thanks to this Stack-Overflow Thread, i got it working like a charm so far. Now, if the user taps on a item in the "SearchPage", a new ContentPage (called "DetailPage") is pushed to the NavigationStack using the following method:

private async Task PushPageAsync(object model, ContentPage page, INavigation navigation)
    {
        page.BindingContext = model;
        await navigation.PushAsync(page).ConfigureAwait(false);
    }

That works without problems. But if the users navigates from the "DetailPage" back to the "SearchPage" by using the Back-Button, the customized Search-Header isn't showing at all.

What I tried:

Using the "OnAppearing" event of the page instead of the "OnElementChanged". That didn't solve the problem at first sight. However, if I add a Task.Delay(500) to the OnAppearing-Method and then add the SearchView again, it is displayed. But this fix seems quite ugly, and if i sleep the app and resume while using the SearchPage, the Search-Widget is showing twice.

So my question is:

Is there a bug in Xamarin or am I doing something wrong?

1 Answers
Related