我正在尝试捕获UWP上TabbedPage
的一次重新捕获事件。
在this page中,我看到您需要创建一个自定义渲染器。当我尝试使用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();
}
}
}
答案 0 :(得分:1)
简短的回答是,据我所知,至少在不深入研究Xamarin的情况下,您无法轻易检测到UWP上的选项卡重新点击/重新选择.Forms源代码有点了解它们如何实现uWP TabbedPageRenderer。
这是我的实现方式:
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/。
答案 1 :(得分:1)
根据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;
}
}
}
答案 2 :(得分:0)
根据您的解释,我已经更新了您的代码,希望对您有所帮助:
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;
}
}