Xamarin表单ControlTemplate TapGestureRecognizer命令绑定

时间:2019-03-21 11:52:46

标签: c# xamarin xamarin.forms controltemplate theming

我有一个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"/>

我设置了包含青色图像的Frame的背景色,以确保显示我的拍子区域。很明显,它在那里,但是点击它永远不会激活TGR和我为其设置的关联命令。

注意:我要填充ContentPresenter的内容具有透明背景,以显示主页的背景图像。这是这种情况的关键,因为很难分辨出什么是最重要的。

1 个答案:

答案 0 :(得分:0)

啊哈!通常,当您着手明确定义问题时,就会激发出解决问题的想法。

我之前遇到过这个问题,但是忘记了: Z ORDER!

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

就像TGR起作用一样。该按钮看起来不那么礼貌。该按钮在ContentPresenter上方的显示效果很好。

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

提示:也许不与模板控件共享空间,但是如果您愿意并且希望模板控件可访问且位于控件的最前面,则可以在模板的下方定义ContentPresenter!

有关模板绑定的说明。

许多地方都指出,当您绑定ControlTemplate控件时,会使用以下语法(例如,在此处绑定IsVisible):

IsVisible="{TemplateBinding BindingContext.ShowBack}"

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