Повторное событие на TabbedPage - PullRequest
0 голосов
/ 20 февраля 2019

Я пытаюсь захватить событие повторного отображения для TabbedPage в UWP.

С этой страницы , я вижу, что вам нужно создать пользовательский рендер.Когда я пытаюсь использовать Xamarin.Forms.Platform.UWP.TabbedPageRenderer, я не могу найти подходящее событие для подписки.

Я пробовал события Tapped и Focused, но, похоже, они не работают так, как я ожидаю.

Как вы обнаруживаете, что на UWP происходит повторное нажатие вкладки?

Вот что я пробовал до сих пор:

public class TabbedPageCustomRenderer : TabbedPageRenderer
{
    private TabbedHomePage _page;
    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);

        if (e.NewElement != null)
        {
            _page = (TabbedHomePage)e.NewElement;
        }
        else
        {
            _page = (TabbedHomePage)e.OldElement;
        }

        //_page.Focused += _page_Focused;
        //this.Control.Tapped += Control_Tapped;

        // what should I subscribe to?
    }

    private async void _page_Focused(object sender, Xamarin.Forms.FocusEventArgs e)
    {
        if (_page?.CurrentPage?.Navigation != null && _page.CurrentPage.Navigation.NavigationStack.Count > 0)
        {
            await _page.CurrentPage.Navigation.PopToRootAsync();
        }
    }

    private async void Control_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
    {
        if (_page?.CurrentPage?.Navigation != null && _page.CurrentPage.Navigation.NavigationStack.Count > 0)
        {
            await _page.CurrentPage.Navigation.PopToRootAsync();
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 20 февраля 2019

Короткий ответ: нет, насколько я могу судить, вы не можете легко обнаружить повторный выбор / повторный выбор вкладки в UWP, по крайней мере, не углубившись в исходный код Xamarin.Forms, чтобы увидеть, как они реализовали uWPTabbedPageRenderer.

Вот как я это реализовал:

public class MainTabPageRenderer : TabbedPageRenderer
{
    private Xamarin.Forms.Page _prevPage;

    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);

        Control.Tapped += Control_Tapped;
        _prevPage = Control.SelectedItem as Xamarin.Forms.Page;
    }

    private async void Control_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
    {
        var src = e.OriginalSource as TextBlock;
        if (src != null
             && src.Name == "TabbedPageHeaderTextBlock"
             && Element is TabReselectDemo.MainPage)
        {
            var newPage = src.DataContext as Xamarin.Forms.Page;
            if (newPage == _prevPage)
            {
                // do your thing here, a tab retap happened, like:
                await newPage.Navigation.PopToRootAsync();
            }
            _prevPage = newPage;
        }
    }
}

TabbedPageHeaderTextBlock является частью внутренних компонентов средства визуализации UWP.Учитывая, что это не задокументировано, это не идеально, поскольку теоретически может измениться в будущей версии Xamarin.Forms, но некоторое время оно было стабильным.

Этого должно быть достаточно, чтобы решить это за вас,но подробнее здесь: https://criticalhittech.com/2017/09/25/tab-reselection-in-xamarin-forms-part-2/.

0 голосов
/ 21 февраля 2019

Исходя из ответа от DavidS, вот код, который я использовал, который также обрабатывает значки на вкладке UWP:

// this is C# 7, so will only work with a recent c# compiler
public class TabbedPageCustomRenderer : TabbedPageRenderer
{
    private Xamarin.Forms.Page _prevPage;

    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);

        Control.Tapped += Control_Tapped;
        _prevPage = Control.SelectedItem as Xamarin.Forms.Page;
    }

    private async void Control_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
    {
        // replace 'TabbedHomePage' with whatever your page type is with the tabs
        if (!(this.Element is TabbedHomePage))
            return;

        switch (e.OriginalSource)
        {
            case Image image when image.Parent is StackPanel:
                {
                    var sp = (StackPanel)image.Parent;

                    var tb = sp.Children.Where(c => c is TextBlock).FirstOrDefault() as TextBlock;

                    await HandleRetab(tb);
                    break;
                }
            case TextBlock tb:
                {
                    await HandleRetab(tb);
                    break;
                }
            default:
                break;
        }

        async Task HandleRetab(TextBlock tb)
        {
            if (tb == null)
                return;

            var newPage = tb.DataContext as Xamarin.Forms.Page;
            if (newPage == _prevPage &&
                tb.Name == "TabbedPageHeaderTextBlock")
            {
                // do your thing here, a tab retap happened, like:
                await newPage.Navigation.PopToRootAsync();
            }

            _prevPage = newPage;
        }
    }
}
0 голосов
/ 20 февраля 2019

На основании вашего объяснения я обновил ваш код, надеюсь, это поможет:

public class TabbedPageCustomRenderer : TabbedPageRenderer
{
    private TabbedHomePage _page;
    bool isRetap = false;
    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);

        if (e.NewElement != null)
        {
            _page = (TabbedHomePage)e.NewElement;
        }
        else
        {
            _page = (TabbedHomePage)e.OldElement;
        }

        //_page.Focused += _page_Focused;
        this.Control.Tapped += Control_Tapped;

        // what should I subscribe to?
    }

    private async void _page_Focused(object sender, Xamarin.Forms.FocusEventArgs e)
    {
        if (_page?.CurrentPage?.Navigation != null && _page.CurrentPage.Navigation.NavigationStack.Count > 0)
        {
            await _page.CurrentPage.Navigation.PopToRootAsync();
        }
    }

    private async void Control_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
    {
        if (isRetap && _page?.CurrentPage?.Navigation != null && _page.CurrentPage.Navigation.NavigationStack.Count > 0)
        {
            await _page.CurrentPage.Navigation.PopToRootAsync();
        }
        isRetap = true;
    }
} 
...