Добавление распознавания жестов длинных нажатий в формах Xamarin
Не могли бы вы сообщить мне, как я могу распознать жест длинного нажатия в приложении 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. Я пытался сделать это, ссылаясь на этот поток Stackru. Но, похоже, он не работает.
Я очень новичок в этом. Любая помощь очень ценится.
2 ответа
Ты можешь использовать Effect
добавить LongPressGestureRecognizer
на любой контроль.
в Forms создайте новый общий эффект.
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 Project
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 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>
Для более подробной информации об эффекте вы можете обратиться сюда
Больше не требуется определять собственный эффект, поскольку
TouchEffect
уже существуют в пакете Xamarin Community Toolkit (который представляет собой пакет, который собирает множество классных многоразовых / общих элементов управления, эффектов, поведения ...).
Пример использования, в котором вы даже можете контролировать длительность длительного нажатия (по умолчанию = 500 мс):
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
<Image Source="{Binding}" HorizontalOptions="Center" VerticalOptions="Center" Aspect="AspectFit" HeightRequest="60"
xct:TouchEffect.LongPressCommand="{Binding LongPressCommand}"
xct:TouchEffect.LongPressDuration="2000"/>
Затем определите
LongPressCommand
который будет вызываться / запускаться через 2 секунды (вы можете настроить
LongPressDuration
единица измерения в мс) нажатия.
ICommand LongPressCommand = new Command(() =>
{
LongPressCount++;
OnPropertyChanged(nameof(LongPressCount));
});
Также так же, как
CommandParameter
у вас есть необязательный
LongPressCommandParameter
, применить анимацию и многое другое.
Ресурс
Документация (в разработке) https://docs.microsoft.com/en-us/xamarin/community-toolkit/