在适用于 Android 和 UWP 的 Xamarin.Forms 项目中,我想定义长按 (Android) 和双击(在 UWP 上)的效果。为此,我做了所有我能找到的事情,在 Android 和 UWP 通用代码中定义了一个适当的
RoutingEffect
类:
/// <summary>
/// Long press on a Control - Double Click in UWP
/// </summary>
public class LongPressedDblClickEffect : RoutingEffect
{
public LongPressedDblClickEffect() : base("MyApp.LongPressedDblClickEffect")
{
}
#region LongPressed
public static readonly BindableProperty LongPressedCommandProperty = BindableProperty.CreateAttached("LongPressedCommand", typeof(ICommand),
typeof(LongPressedEffect), null);
public static ICommand GetLongPressedCommand(BindableObject view)
{
return (ICommand)view.GetValue(LongPressedCommandProperty);
}
public static void SetLongPressedCommand(BindableObject view, ICommand value, object parameter)
{
view.SetValue(LongPressedCommandProperty, value);
SetLongPressedCommandParameter(view, parameter);
}
public static void SetLongPressedCommand(BindableObject view, ICommand value)
{
view.SetValue(LongPressedCommandProperty, value);
}
public static readonly BindableProperty LongPressedCommandParameterProperty =
BindableProperty.CreateAttached("LongPressedCommandParameter", typeof(object), typeof(LongPressedEffect), null);
public static object GetLongPressedCommandParameter(BindableObject view)
{
return view.GetValue(LongPressedCommandParameterProperty);
}
public static void SetLongPressedCommandParameter(BindableObject view, object value)
{
view.SetValue(LongPressedCommandParameterProperty, value);
}
#endregion
#region Clicked
public static readonly BindableProperty ClickCommandProperty = BindableProperty.CreateAttached("ClickCommand", typeof(ICommand),
typeof(LongPressedEffect), null);
public static ICommand GetClickCommand(BindableObject view)
{
return (ICommand)view.GetValue(ClickCommandProperty);
}
public static void SetClickCommand(BindableObject view, ICommand value, object parameter)
{
view.SetValue(ClickCommandProperty, value);
SetClickCommandParameter(view, parameter);
}
public static void SetClickCommand(BindableObject view, ICommand value)
{
view.SetValue(ClickCommandProperty, value);
}
public static readonly BindableProperty ClickCommandParameterProperty =
BindableProperty.CreateAttached("ClickCommandParameter", typeof(object), typeof(LongPressedEffect), null);
public static object GetClickCommandParameter(BindableObject view)
{
return view.GetValue(ClickCommandParameterProperty);
}
public static void SetClickCommandParameter(BindableObject view, object value)
{
view.SetValue(ClickCommandParameterProperty, value);
}
#endregion
}
对于 UWP,我定义了以下类:
[assembly: ResolutionGroupName("MyApp")]
[assembly: ExportEffect(typeof(MyNamespace.UWP.DoubleClickEffect), "LongPressedDblClickEffect")]
namespace MyNamespace.UWP
{
public class DoubleClickEffect : PlatformEffect
{
private bool _attached;
public bool IsSingleTap { get; set; }
public DoubleClickEffect()
{
}
/// <summary>
/// Attach handlers needed for this event
/// </summary>
protected override void OnAttached()
{
if (!_attached)
{
if (Control != null)
{
Control.IsTapEnabled = true;
Control.IsDoubleTapEnabled = true;
Control.Tapped += Tapped;
Control.DoubleTapped += DoubleTapped;
}
else
{
Container.IsTapEnabled = true;
Container.IsDoubleTapEnabled = true;
Container.Tapped += Tapped;
Container.DoubleTapped += DoubleTapped;
}
_attached = true;
}
}
/// <summary>
/// Remove handlers on detach
/// </summary>
protected override void OnDetached()
{
if (_attached)
{
if (Control != null)
{
Control.Tapped -= Tapped;
Control.DoubleTapped -= DoubleTapped;
}
else
{
Container.Tapped -= Tapped;
Container.DoubleTapped -= DoubleTapped;
}
_attached = false;
}
}
private void DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
IsSingleTap = false;
var command = LongPressedDblClickEffect.GetLongPressedCommand(Element);
command?.Execute(LongPressedDblClickEffect.GetLongPressedCommandParameter(Element));
}
private async void Tapped(object sender, TappedRoutedEventArgs e)
{
IsSingleTap = true;
await Task.Delay(200);
if (IsSingleTap)
{
var command = LongPressedDblClickEffect.GetClickCommand(Element);
command?.Execute(LongPressedDblClickEffect.GetClickCommandParameter(Element));
}
}
}
}
在 XAML 中:
<Label Text="{Binding Name}"
...
mycode:LongPressedDblClickEffect.LongPressedCommand="{Binding LongPressCommand}"
FontSize="16" >
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ShortPressCommand}" />
</Label.GestureRecognizers>
<Label.Effects>
<code:LongPressedDblClickEffect />
</Label.Effects></Label>
正确调用UWP代码并注册事件。但是,
Tapped
事件仅在双击时触发一次,并且 DoubleTapped
永远不会被调用。我在网络上没有找到任何有关此问题的信息。所以我不认为这是一个错误,而是我这边的一个错误。
谁可以帮忙?
这个问题的原因是
TapGestureRecognizer
和我的LongPressedDblClickEffect
的混合。
将 XAML 更改为
后<Label Text="{Binding Name}" ...
Style="{DynamicResource ListItemTextStyle}"
code:LongPressedDblClickEffect.LongPressedCommand="{Binding LongPressCommand}"
code:LongPressedDblClickEffect.ClickCommand="{Binding ShortPressCommand}"
FontSize="16" >
<Label.Effects>
<code:LongPressedDblClickEffect />
</Label.Effects>
双击事件被正确触发。