Xavier Rubio Jansana

Xavier Rubio Jansana

Mobile engineer.
Android and iOS.
Scuba diver.

© 2024

Disabling right click and swipe on Windows Store Apps without using code-behind

A month ago I was working on a Windows Store project and I needed to disable right click and swipe for some grid controls. Of course, the property to disable/enable swipe is well known: IsSwipeEnabled. Just put a false there and you’re ready to go! But I could not find an equivalent property to disable right-click, and IsSwipeEnabled does exactly what it says: disable swipe touch gesture, but has no effect on right-click (which you may expect it will, because right-click is the equivalent manipulation using mouse).

Anyway, I found that the only way to disable right-click was to handle the right-click event, using code. So, my first thought was using code behind, and add an event handler and tell the remaining handlers that I handled the event already. So an event handler like this one should do it:

private static void RightClickEnabledProperty_RightTapped(object sender, Windows.UI.Xaml.Input.RightTappedRoutedEventArgs e)
{
    e.Handled = true;
}

But then, I thought I rather had a property implemented to be able to use it whenever I wanted without having to add more code behind to each XAML. So, here is the implementation for this property:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;

namespace App.Properties
{
    public class RightClickEnabledProperty
    {
        public static readonly DependencyProperty IsRightClickEnabledProperty =
            DependencyProperty.RegisterAttached("IsRightClickEnabled", typeof(bool), typeof(RightClickEnabledProperty),
                                                new PropertyMetadata(true, IsRightClickEnabledPropertyChanged));


        public static void SetIsRightClickEnabled(DependencyObject attached, bool value)
        {
            attached.SetValue(IsRightClickEnabledProperty, value);
        }


        public static bool GetIsRightClickEnabled(DependencyObject attached)
        {
            return (bool)attached.GetValue(IsRightClickEnabledProperty);
        }


        private static void IsRightClickEnabledPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            bool? value = e.NewValue as bool?;
            if (!value.HasValue || value.Value)
                (d as UIElement).RightTapped -= RightClickEnabledProperty_RightTapped;
            else
                (d as UIElement).RightTapped += RightClickEnabledProperty_RightTapped;
        }

        private static void RightClickEnabledProperty_RightTapped(object sender, Windows.UI.Xaml.Input.RightTappedRoutedEventArgs e)
        {
            UIElement control = sender as UIElement;
            if (control == null)
                return;

            if (!GetIsRightClickEnabled(control))
                e.Handled = true;
        }

    }
}

The downside of this is that the property must be defined in the item itself (usually in the top-level control or container inside the ItemTemplate), while the IsSwipeEnabled property is defined in the Grid or ListView itself.

See an example (remember to define the namespace in the root node of the XAML, like: xmlns:properties="using:App.Properties"):

<ListView
    ItemsSource="{Binding ElementList}"
    SelectedItem="{Binding SelectedElement, Mode=TwoWay}"
    IsSwipeEnabled="False"
    SelectionMode="Single">
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBlock
                Text="{Binding ElementName}"
                properties:RightClickEnabledProperty.IsRightClickEnabled="False"/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Hope this helps to keep your XAML a little more clean, with less code-behind.