Xamarin Forms ControlTemplate TapGestureRecognizer命令绑定

问题描述 投票:1回答:1

我有一个ControlTemplate我打算用来为我的应用程序中的大多数页面提供基本功能。

关于这个想法的好参考:

在尝试将TapGestureRecognizer绑定到绑定上下文中的ICommand时,我遇到了一些奇怪的事情。我能够使用Button在我的View中绑定到ICommand属性,但完全没有使用TapGestureRecognizer。

我有一个后箭头图像,我想在大多数所有页面上用于向后导航,如果我可以将命令绑定到我的View(就像使用按钮时那样),使用带有TapGestureRecognizer的图像似乎很自然。

下面框架上方的按钮是一个实验,用于证明命令编码正常。奇怪的是,按钮与其命令的完全相同的绑定工作得很好,而TGR没有做任何事情。

我的ControlTemplate XAML的一部分:

<Button Grid.Row="1" HorizontalOptions="Start" VerticalOptions="Start" IsVisible="{TemplateBinding BindingContext.ShowBack}" Text ="Back" Command="{TemplateBinding BindingContext.BackNavCommand}" Margin="90,0,0,0"/>

<!-- LATE EDIT - The TGR on this Frame is doomed not to work.  The whole frame should be defined BELOW the Content Presenter.  Read on below for why. -->
<Frame Grid.Row="1" HorizontalOptions="Start" VerticalOptions="Start" IsVisible="{TemplateBinding BindingContext.ShowBack}" BackgroundColor="Cyan" BorderColor="Transparent" HasShadow="False" HeightRequest="50" WidthRequest="50">
<Frame.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform ="iOS" Value="5,25,0,0"/>
<On Platform ="Android" Value="5,5,0,0"/>
<On Platform ="UWP" Value="5,5,0,0"/>
</OnPlatform>
</Frame.Padding>
<Frame.GestureRecognizers>
<TapGestureRecognizer x:Name="backTapped" Command="{TemplateBinding BindingContext.BackNavCommand}" />
</Frame.GestureRecognizers>
<Image x:Name="backImage"  Source="back.png" Aspect="AspectFit" HeightRequest="20" WidthRequest="30" VerticalOptions="Center" HorizontalOptions="Center" InputTransparent="True"/>
</Frame>
<ContentPresenter Grid.Row="1"/>

我设置包含图像Cyan的Frame的backgroundcolor,以确保我的tap区域显示出来。它显然在那里,但是点击它永远不会激活TGR以及我为其设置的相关命令。

注意:我填写ContentPresenter的内容具有透明背景,以显示主页面的支持图像。这是这种情况的关键,因为告诉什么是前面的东西是很棘手的。

c# xamarin xamarin.forms controltemplate theming
1个回答
0
投票

啊哈!正如经常发生的那样,当您开始明确定义问题时,您会激发关于如何解决问题的想法。

我以前遇到过这个,但忘记了:Z ORDER!

我知道我的ControlTemplate控件将共享Content Presenter的空间,因为它全部放在Grid.Row 1.要使TapGestureRecognizer正常工作,我需要在ContentPresenter下面的ControlTemplate XAML中定义它。通过这样做,控件仍然会在完全相同的位置卷起,但是它会在模板内容的TOP上结束,因为它是稍后定义的(在可视化堆栈中可以说更高)。

就像TGR一样。这个按钮似乎没那么礼貌了。按钮工作正常,如此处所示,位于ContentPresenter上方。

注意:我发现这是一种非常好的方法,可以在我的ControlTemplate中重复使用ActivityIndi​​cator。同样,它必须低于ContentPreseneter,否则微调器将显示在后台,输入字段之间等。

提示:也许不要与模板化控件共享空间,但是如果你这样做,并且你希望模板化控件可以在前面访问,那么在模板下面定义它们ContentPresenter!

关于TemplateBinding的注意事项。

许多地方已经注意到,当您绑定ControlTemplate控件时,您使用此语法(例如,绑定IsVisible):

IsVisible="{TemplateBinding BindingContext.ShowBack}"

这里BindingContext的确切含义取决于......如果你的页面在其构造函数中将BindingContext设置为“this”,那么模板将在视图中查找模板与内容包装的可绑定属性“ShowBack”。 但是,如果将模板包含的视图的BindingContext设置为ViewModel对象,那么BindingContext将在那里查找名为ShowBack的可绑定属性。从实验中学到了这一点,并认为我会分享。

© www.soinside.com 2019 - 2024. All rights reserved.