在 LongPress 上显示 ContextMenu 以获取 xamarin 表单中的视图

Posted

技术标签:

【中文标题】在 LongPress 上显示 ContextMenu 以获取 xamarin 表单中的视图【英文标题】:Display ContextMenu on LongPress for a View in xamarin forms 【发布时间】:2018-12-14 05:44:25 【问题描述】:

嗨, 您能否告诉我如何在长按效果时显示上下文菜单。我添加了一个带有效果的 ListView,但长按列表视图后上下文菜单没有弹出。

MainPage.xaml

    <ContentView x:Name="Parent" 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>


                        <ListView x:Name="MainListView" local:LongPressedEffect.Command="Binding ShowAlertCommand" local:LongPressedEffect.CommandParameter="Binding .">
                            <ListView.Effects>
                                <local:LongPressedEffect />
                            </ListView.Effects>
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <ViewCell>                                            
                                        <ViewCell.ContextActions>
                                            <MenuItem Text="Add" ></MenuItem>
                                            <MenuItem Text="Delete" ></MenuItem>
                                            <MenuItem Text="Edit" ></MenuItem>
                                        </ViewCell.ContextActions>
                                    </ViewCell>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>

                    </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>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:DataGridColumn Title="Percentage" PropertyName="Percentage"/>
            <dg:DataGridColumn Title="Streak" PropertyName="Streak" Width="0.7*"/>
        </dg:DataGrid.Columns>
</ContentView> 

LongPressedEffect.cs

 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)
    

        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);
    

androidLongPressedEffect.cs

public class AndroidLongPressedEffect : PlatformEffect

    private bool _attached;

    /// <summary>
    /// Initializer to avoid linking out
    /// </summary>
    public static void Initialize()  
     /// <summary>
    /// Initializes a new instance of the
    /// <see cref="T:Yukon.Application.AndroidComponents.Effects.AndroidLongPressedEffect"/> class.
    /// Empty constructor required for the odd Xamarin.Forms reflection constructor search
    /// </summary>
    public AndroidLongPressedEffect()
    
    

    /// <summary>
    /// Apply the handler
    /// </summary>
    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;
        
    

    /// <summary>
    /// Invoke the command if there is one
    /// </summary>
    /// <param name="sender">Sender.</param>
    /// <param name="e">E.</param>
    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));            
    

    /// <summary>
    /// Clean the event handler on detach
    /// </summary>
    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;
        
    

非常感谢任何帮助! 如果需要更多信息,请告诉我。

【问题讨论】:

【参考方案1】:

您可以将App.cs 中的属性设置为currentPage。

public static ContentPage currentPage;

并将其设置在包含您的 listView 的 contentPage 中。

public xxxPage()
 
    InitializeComponent();

    App.currentPage = this;

 

LongPressedEffect.cs

public static ICommand GetCommand(BindableObject view)
 

   //do something you want
   App.currentPage.DisplayActionSheet("ActionSheet: Send to?", "Cancel", null, "Email", "Twitter", "Facebook");
   return (ICommand)view.GetValue(CommandProperty);
 

【讨论】:

张。非常感谢。

以上是关于在 LongPress 上显示 ContextMenu 以获取 xamarin 表单中的视图的主要内容,如果未能解决你的问题,请参考以下文章

ListView 上的 LongPress 与 Android 上的超链接

Flutter - 使用 Material 在 longpress 上更改 appbar

Detox/Appium tap、multiTap 和 longPress 在元素上不起作用

LongPress on List 确实在 iPad 上重新排序,但如何在 iPhone 上重新排序

UIScrollView、UIMenuController 和 LongPress 手势

iOS7 Xcode 5 升级让 longpress 崩溃应用