在Xamarin表单中添加长按手势识别器

时间:2018-12-12 07:55:21

标签: xamarin.forms xamarin.android long-press

能否让我知道如何在Xamarin Forms应用程序中识别长按手势?

这是我参考以下线程创建的xaml页面:Xamarin.forms.DataGrid

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataGridSample_01"
xmlns:dg="clr-namespace:Xamarin.Forms.DataGrid;assembly=Xamarin.Forms.DataGrid"
x:Class="DataGridSample_01.MainPage">

 <ContentView BackgroundColor="White" Padding="20" >
  <dg:DataGrid ItemsSource="{Binding Data}" SelectionEnabled="True" RowHeight="70" HeaderHeight="50" BorderColor="#CCCCCC" HeaderBackground="#E0E6F8" ActiveRowColor="#8899AA">
     <dg:DataGrid.Columns>
     <dg:DataGridColumn Title="Logo" PropertyName="Logo" Width="50" SortingEnabled="False">
        <dg:DataGridColumn.CellTemplate>
           <DataTemplate>
              <Image Source="{Binding}" HorizontalOptions="Center" VerticalOptions="Center" Aspect="AspectFit" HeightRequest="60" />
           </DataTemplate>
        </dg:DataGridColumn.CellTemplate>
     </dg:DataGridColumn>
     <dg:DataGridColumn Title="Team" PropertyName="Name" Width="2*" >
     </dg:DataGridColumn>
     <dg:DataGridColumn Title="Win" PropertyName="Win" Width="2*">
        <dg:DataGridColumn.CellTemplate>
           <DataTemplate>
              <Picker x:Name="Fruits" Title="Fruits" HorizontalOptions="FillAndExpand">
                 <Picker.Items>
                    <x:String>Apple</x:String>
                    <x:String>Mango</x:String>
                    <x:String>PineApple</x:String>
                    <x:String>Orange</x:String>
                 </Picker.Items>
              </Picker>
           </DataTemplate>
        </dg:DataGridColumn.CellTemplate>
     </dg:DataGridColumn>
     <dg:DataGridColumn Title="Loose" PropertyName="Loose"  Width="1*">                    
     </dg:DataGridColumn>
     <dg:DataGridColumn PropertyName="Home">
        <dg:DataGridColumn.FormattedTitle>
           <FormattedString>
              <Span Text="Home" ForegroundColor="Black" FontSize="13" FontAttributes="Bold"/>
              <Span Text=" (win-loose)" ForegroundColor="#333333" FontSize="11" />
           </FormattedString>
        </dg:DataGridColumn.FormattedTitle>
     </dg:DataGridColumn>
     <dg:DataGrid.RowsBackgroundColorPalette>
        <dg:PaletteCollection>
           <Color>#FFFFFF</Color>
        </dg:PaletteCollection>
     </dg:DataGrid.RowsBackgroundColorPalette>
  </dg:DataGrid>
 </ContentView>
</ContentPage>

我想在Image Control上添加一个Long Press Gesture识别器。我尝试参考此StackOverflow Thread进行操作。但这似乎不起作用。

我对此很陌生。 非常感谢您的帮助。

2 个答案:

答案 0 :(得分:6)

不再需要定义自己的效果,因为TouchEffect已经存在于Xamarin Community Toolkit包中(这是一个集合了很多很酷的可重用/通用控件、效果、行为、转换器的包...).

xaml 命名空间:

 xmlns:xct="http://xamarin.com/schemas/2020/toolkit"

使用示例

您可以设置触发命令所需的长按持续时间,或保留默认值 = 500 毫秒。在本例中,LongPressCommand 将在 2 秒后触发/触发。

<Image Source="{Binding}" HorizontalOptions="Center" VerticalOptions="Center"
       Aspect="AspectFit" HeightRequest="60"
       xct:TouchEffect.LongPressCommand="{Binding LongPressCommand}"
       xct:TouchEffect.LongPressDuration="2000"/>
ICommand LongPressCommand = new Command(() =>
            {
                LongPressCount++;
                OnPropertyChanged(nameof(LongPressCount));
            });

此外,与 CommandParameter 一样,您有一个可选的 LongPressCommandParameter,您可以在其中将自定义参数绑定到您的命令。

资源

文档(工作中)https://docs.microsoft.com/en-us/xamarin/community-toolkit/

回购 https://github.com/xamarin/XamarinCommunityToolkit/

https://www.youtube.com/watch?v=BcFlZMhPmVk

答案 1 :(得分:0)

您可以使用EffectLongPressGestureRecognizer添加到任何控件中。

  

在表单中,创建一个新的共享效果。

using System;
using System.Windows.Input;
using Xamarin.Forms;

namespace App15
{
  public class LongPressedEffect : RoutingEffect
  {
    public LongPressedEffect() : base("MyApp.LongPressedEffect")
    {

    }

    public static readonly BindableProperty CommandProperty = BindableProperty.CreateAttached("Command", typeof(ICommand), typeof(LongPressedEffect), (object)null);
    public static ICommand GetCommand(BindableObject view)
    {

        //do something you want 
        Console.WriteLine("long press Gesture recognizer has been striked");


        return (ICommand)view.GetValue(CommandProperty);
    }

    public static void SetCommand(BindableObject view, ICommand value)
    {
        view.SetValue(CommandProperty, value);

    }


    public static readonly BindableProperty CommandParameterProperty = BindableProperty.CreateAttached("CommandParameter", typeof(object), typeof(LongPressedEffect), (object)null);
    public static object GetCommandParameter(BindableObject view)
    {

        return view.GetValue(CommandParameterProperty);
    }

    public static void SetCommandParameter(BindableObject view, object value)
    {
        view.SetValue(CommandParameterProperty, value);
    }
  }
}
  

在Android项目中

using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

using App15;
using App15.Droid;    

[assembly: ResolutionGroupName("MyApp")]
[assembly: ExportEffect(typeof(AndroidLongPressedEffect), "LongPressedEffect")]
namespace AndroidAppNamespace.Effects
{

  public class AndroidLongPressedEffect : PlatformEffect
  {
    private bool _attached;

    public static void Initialize() { }

    public AndroidLongPressedEffect()
    {
    }

    protected override void OnAttached()
    {
        //because an effect can be detached immediately after attached (happens in listview), only attach the handler one time.
        if (!_attached)
        {
            if (Control != null)
            {
                Control.LongClickable = true;
                Control.LongClick += Control_LongClick;
            }
            else
            {
                Container.LongClickable = true;
                Container.LongClick += Control_LongClick;
            }
            _attached = true;
        }
    }


    // Invoke the command if there is one
    private void Control_LongClick(object sender, Android.Views.View.LongClickEventArgs e)
    {
        Console.WriteLine("Invoking long click command");
        var command = LongPressedEffect.GetCommand(Element);
        command?.Execute(LongPressedEffect.GetCommandParameter(Element));
    }


    protected override void OnDetached()
    {
        if (_attached)
        {
            if (Control != null)
            {
                Control.LongClickable = true;
                Control.LongClick -= Control_LongClick;
            }
            else
            {
                Container.LongClickable = true;
                Container.LongClick -= Control_LongClick;
            }
            _attached = false;
        }
    }
}
  

在iOS项目中

using Foundation;
using UIKit;
using App15;
using App15.iOS;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ResolutionGroupName("MyApp")]
[assembly: ExportEffect(typeof(iOSLongPressedEffect), "LongPressedEffect")]
namespace App15.iOS
{
  public class iOSLongPressedEffect : PlatformEffect
  {
    private bool _attached;
    private readonly UILongPressGestureRecognizer _longPressRecognizer;

    public iOSLongPressedEffect()
    {
        _longPressRecognizer = new UILongPressGestureRecognizer(HandleLongClick);
    }


    protected override void OnAttached()
    {
        //because an effect can be detached immediately after attached (happens in listview), only attach the handler one time
        if (!_attached)
        {
            Container.AddGestureRecognizer(_longPressRecognizer);
            _attached = true;
        }
    }


    // Invoke the command if there is one       
    private void HandleLongClick(UILongPressGestureRecognizer sender)
    {
        if(sender.State==UIGestureRecognizerState.Began)
        {
            var command = LongPressedEffect.GetCommand(Element);
            command?.Execute(LongPressedEffect.GetCommandParameter(Element));
        }


    }

    protected override void OnDetached()
    {
        if (_attached)
        {
            Container.RemoveGestureRecognizer(_longPressRecognizer);
            _attached = false;
        }
    }

  }
}

现在,您可以向控件添加LongPressGestureRecognizer。例如Label或Image。

<Label Text="Long Press Me!" local:LongPressedEffect.Command="{Binding ShowAlertCommand}" local:LongPressedEffect.CommandParameter="{Binding .}">
  <Label.Effects>
      <local:LongPressedEffect />
  </Label.Effects>
</Label>

<Image Source="{Binding}" local:LongPressedEffect.Command="{Binding ShowAlertCommand}" local:LongPressedEffect.CommandParameter="{Binding .}">
   <Image.Effects>
        <local:LongPressedEffect />
   </Image.Effects>
</Image>

有关效果的更多详细信息,您可以参考here