Stacklayout 上所有 3 个平台(Android、iOS、UWP)中的 Xamarin 长按事件

Posted

技术标签:

【中文标题】Stacklayout 上所有 3 个平台(Android、iOS、UWP)中的 Xamarin 长按事件【英文标题】:Xamarin Long Press event in all 3 platforms (Android,iOS,UWP) on Stacklayout 【发布时间】:2019-05-23 10:23:43 【问题描述】:

我想要用于长按事件的任何 Nuget 包或任何自定义组件,我想在所有 3 个平台的 listview 中使用它们。我有一个关于 androidios 的解决方案,但没有找到任何适用于 UWP 的解决方案。 有人可以帮我解决这个问题吗? 提前致谢

【问题讨论】:

How to make long press gesture in Xamarin Forms?的可能重复 您可以使用 MultiGestureView 插件,它使您能够在不同的平台上使用 LongPress、Tap 和 Right Click:nuget.org/packages/Xam.Plugin.MultiGestureView 另外,您可以只在 listView 的视单元上使用 ContextActions,而不是创建长按手势。 【参考方案1】:

!!!触摸可以产生保持动作,但鼠标设备通常不能。 https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.uielement.holding?view=winrt-19041

PLC类:

  namespace MyNamespace.Effects
    
    /// <summary>
    /// Эффект длительного нажатия на элемент управления (общая реализация)
    /// </summary>
    public class LongPressedEffect : RoutingEffect
    
        public LongPressedEffect() : base("LongPressedEffect")
        
        
    #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 LongPressed

    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("MyNamespace")]
[assembly: ExportEffect(typeof(MyNamespace.UWP.Effects.UWPLongPressedEffect), "LongPressedEffect")]
namespace MyNamespace.UWP.Effects


    public class UWPLongPressedEffect : PlatformEffect
    
        private bool _attached;

        public UWPLongPressedEffect()
        

        

        /// <summary>
        /// Прикрепление обработчика, необходимого для эффекта
        /// </summary>
        protected override void OnAttached()
        
            if (!_attached)
            
                if (Control != null)
                
                    Control.IsHoldingEnabled = true;
                    Control.Tapped += Tapped;
                    Control.Holding += Holding;
                
                else
                
                    Container.IsHoldingEnabled = true;
                    Container.Tapped += Tapped;
                    Container.Holding += Holding;
                
                _attached = true;
            
        

        /// <summary>
        /// Отсоединение обработчика для эффекта
        /// </summary>
        protected override void OnDetached()
        
            if (_attached)
            
                if (Control != null)
                
                    Control.IsHoldingEnabled = true;
                    Control.Tapped -= Tapped;
                    Control.Holding -= Holding;
                
                else
                
                    Container.IsHoldingEnabled = true;
                    Container.Tapped -= Tapped;
                    Container.Holding -= Holding;
                
                _attached = false;
            
        

        private void Tapped(object sender, TappedRoutedEventArgs e)
        
            var command = LongPressedEffect.GetClickCommand(Element);
            command?.Execute(LongPressedEffect.GetClickCommandParameter(Element));
        

        private void Holding(object sender, HoldingRoutedEventArgs e)
        
            var command = LongPressedEffect.GetLongPressedCommand(Element);
            command?.Execute(LongPressedEffect.GetLongPressedCommandParameter(Element));
        
    

【讨论】:

您能否提供一些上下文,您的答案应该如何解决问题? 添加了来自 PLC 的调用上下文。

以上是关于Stacklayout 上所有 3 个平台(Android、iOS、UWP)中的 Xamarin 长按事件的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin - NavigationPage.TitleView 内的 StackLayout 不会使用所有空间?

嵌套在水平 StackLayout 中时,多行标签不会调整父 StackLayout 的大小

如何在stacklayout xamarin表单pcl上填充图像

StackLayout

Xamarin 中 StackLayout 内的 ListView 未根据列表视图项高度扩展

HarmonyOS之常用布局StackLayout的使用