protected override async void OnTapped(TappedRoutedEventArgs e)
        {
            if (!e.Handled)
            {
                var source = e.OriginalSource as FrameworkElement;
                if (source != null)
                {
                    var attr = DataContext as PersistentObjectAttribute;
                    if (attr != null)
                    {
                        var args = new AttributeContextMenuArgs(attr);
                        ((StoreHooks)Service.Current.Hooks).AttributeContextMenu(args);
                        if (args.Commands.Count > 0)
                        {
                            if (args.AutoExecuteFirst && args.Commands.Count == 1)
                                args.Commands[0].Invoked(args.Commands[0]);
                            else
                            {
                                var popupMenu = new PopupMenu();
                                args.Commands.Run(popupMenu.Commands.Add);

                                var point = source.TransformToVisual(null).TransformPoint(e.GetPosition(this));
                                await popupMenu.ShowAsync(point);
                            }

                            e.Handled = true;
                        }
                    }
                }
            }

            base.OnTapped(e);
        }
        private void HandleTapAndHold(GestureEventArgs e, bool alwaysOpen = false)
        {
            if (!e.Handled)
            {
                var source = e.OriginalSource as FrameworkElement;
                if (source != null)
                {
                    var attr = DataContext as PersistentObjectAttribute;
                    if (attr != null)
                    {
                        var menu = ContextMenuService.GetContextMenu(this);
                        if (menu.Items.Count > 0)
                            menu.Items.Clear();

                        var args = new AttributeContextMenuArgs(attr);
                        ((PhoneHooks)Service.Current.Hooks).AttributeContextMenu(args);
                        if (args.Commands.Count > 0)
                        {
                            if (!alwaysOpen && args.AutoExecuteFirst && args.Commands.Count == 1)
                                args.Commands[0].Action(attr);
                            else
                            {
                                args.Commands.Run(cmd =>
                                {
                                    var menuItem = new MenuItem { DataContext = cmd, Header = cmd.Text };
                                    menuItem.Click += (_, __) => cmd.Action(attr);
                                    menu.Items.Add(menuItem);
                                });

                                menu.IsOpen = true;
                            }
                        }

                        e.Handled = true;
                    }
                }
            }
        }