Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions 11.0/UserInterface/Gestures/LongPressGesture/LongPressGesture.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.0.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LongPressGesture", "LongPressGesture\LongPressGesture.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.Build.0 = Release|Any CPU
{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B2C3D4E5-F6A7-8901-BCDE-F23456789012}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:LongPressGesture"
x:Class="LongPressGesture.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace LongPressGesture;

public partial class App : Application
{
public App()
{
InitializeComponent();
}

protected override Window CreateWindow(IActivationState? activationState)
{
return new Window(new MainPage())
{
Title = "Long Press Gesture Demo - .NET MAUI"
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
global using Microsoft.Maui.Controls;
global using Microsoft.Maui.Controls.Xaml;
global using Microsoft.Maui.Controls.Shapes;
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net11.0-android;net11.0-ios;net11.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net11.0-windows10.0.19041.0</TargetFrameworks>

<OutputType>Exe</OutputType>
<RootNamespace>LongPressGesture</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<MauiEnableXamlCBindingWithSourceCompilation>true</MauiEnableXamlCBindingWithSourceCompilation>

<!-- Display name -->
<ApplicationTitle>LongPressGesture</ApplicationTitle>

<!-- App Identifier -->
<ApplicationId>com.companyname.longpressgesture</ApplicationId>

<!-- Versions -->
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>

<WindowsPackageType>None</WindowsPackageType>

<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">17.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">23.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
</PropertyGroup>

<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />

<!-- Splash Screen -->
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />

<!-- Images -->
<MauiImage Include="Resources\Images\*" />
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />

<!-- Custom Fonts -->
<MauiFont Include="Resources\Fonts\*" />

<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="$(DotNetVersion)" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:LongPressGesture.ViewModels"
x:Class="LongPressGesture.MainPage"
x:DataType="vm:LongPressViewModel"
BackgroundColor="#F0F2F5">

<ScrollView>
<VerticalStackLayout Padding="20,40" Spacing="20">

<!-- Title -->
<Label Text="Long Press Gesture"
FontSize="28"
FontAttributes="Bold"
TextColor="#512BD4"
HorizontalOptions="Center" />

<Label Text="Press and hold to interact with the elements below"
FontSize="14"
TextColor="#666666"
HorizontalOptions="Center"
HorizontalTextAlignment="Center" />

<!-- ============================================================ -->
<!-- DEMO 1: BoxView with LongPressGestureRecognizer -->
<!-- Shows Command, MinimumPressDuration, AllowableMovement, -->
<!-- LongPressing event for state tracking, and GetPosition() -->
<!-- ============================================================ -->

<Label Text="Long Press on BoxView"
FontSize="18"
FontAttributes="Bold"
TextColor="#333333"
Margin="0,10,0,0" />

<Label Text="Hold for 750ms (Android uses system default). Color changes on completion."
FontSize="13"
TextColor="#888888" />

<!-- <docregion_longpress_boxview> -->
<BoxView x:Name="InteractiveBox"
Color="{Binding BoxColor}"
BackgroundColor="Transparent"
HeightRequest="150"
WidthRequest="300"
CornerRadius="15"
HorizontalOptions="Center">
<BoxView.GestureRecognizers>
<TapGestureRecognizer Tapped="OnBoxTapped" />
<LongPressGestureRecognizer
Command="{Binding LongPressCommand}"
CommandParameter="BoxView"
MinimumPressDuration="750"
AllowableMovement="20"
LongPressed="OnLongPressed"
LongPressing="OnLongPressing" />
</BoxView.GestureRecognizers>
</BoxView>
<!-- </docregion_longpress_boxview> -->

<!-- State and position readout -->
<Border BackgroundColor="White"
Padding="15"
StrokeThickness="0"
HorizontalOptions="Center">
<Border.StrokeShape>
<RoundRectangle CornerRadius="10" />
</Border.StrokeShape>
<Border.Shadow>
<Shadow Brush="Black" Opacity="0.1" Radius="6" Offset="0,3" />
</Border.Shadow>
<VerticalStackLayout Spacing="6">
<Label Text="{Binding GestureStatus}"
FontSize="16"
FontAttributes="Bold"
TextColor="#2E2E2E"
HorizontalTextAlignment="Center" />
<Label Text="{Binding LongPressState}"
FontSize="13"
TextColor="#512BD4"
HorizontalTextAlignment="Center" />
<Label Text="{Binding PositionText}"
FontSize="13"
TextColor="#888888"
HorizontalTextAlignment="Center" />
</VerticalStackLayout>
</Border>

<!-- ============================================================ -->
<!-- DEMO 2: NumberOfTouchesRequired (iOS/Mac Catalyst only) -->
<!-- ============================================================ -->

<VerticalStackLayout x:Name="MultiTouchSection" Spacing="10">

<Label Text="Two-Finger Long Press"
FontSize="18"
FontAttributes="Bold"
TextColor="#333333"
Margin="0,10,0,0" />

<Label Text="Requires two fingers (iOS/Mac Catalyst only)."
FontSize="13"
TextColor="#888888" />

<!-- <docregion_multitouch> -->
<BoxView x:Name="MultiTouchBox"
Color="Teal"
BackgroundColor="Transparent"
HeightRequest="100"
WidthRequest="300"
CornerRadius="15"
HorizontalOptions="Center">
<BoxView.GestureRecognizers>
<LongPressGestureRecognizer
NumberOfTouchesRequired="2"
LongPressed="OnMultiTouchLongPressed" />
</BoxView.GestureRecognizers>
</BoxView>
<!-- </docregion_multitouch> -->

<Label x:Name="MultiTouchStatus"
Text="Waiting for two-finger long press..."
FontSize="13"
TextColor="#888888"
HorizontalOptions="Center" />

</VerticalStackLayout>

<!-- ============================================================ -->
<!-- DEMO 3: Combining LongPress with Tap on the same element -->
<!-- ============================================================ -->

<Label Text="Tap + Long Press on Image"
FontSize="18"
FontAttributes="Bold"
TextColor="#333333"
Margin="0,10,0,0" />

<Label Text="Tap shows alert. Long press shows context info."
FontSize="13"
TextColor="#888888" />

<!-- <docregion_combined_gestures> -->
<Border StrokeThickness="0"
BackgroundColor="White"
HorizontalOptions="Center"
Padding="10">
<Border.StrokeShape>
<RoundRectangle CornerRadius="15" />
</Border.StrokeShape>
<Border.Shadow>
<Shadow Brush="Black" Opacity="0.15" Radius="10" Offset="0,5" />
</Border.Shadow>
<Image Source="dotnet_bot.png"
HeightRequest="180"
WidthRequest="180">
<Image.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding TapCommand}"
CommandParameter="dotnet_bot"
Tapped="OnImageTapped" />
<LongPressGestureRecognizer
MinimumPressDuration="500"
LongPressed="OnImageLongPressed" />
</Image.GestureRecognizers>
</Image>
</Border>
<!-- </docregion_combined_gestures> -->

<Label Text="{Binding ImageStatus}"
FontSize="14"
FontAttributes="Bold"
TextColor="#2E2E2E"
HorizontalOptions="Center"
HorizontalTextAlignment="Center" />

</VerticalStackLayout>
</ScrollView>

</ContentPage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using LongPressGesture.ViewModels;

namespace LongPressGesture;

public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
BindingContext = new LongPressViewModel();

// Demo 2 (two-finger long press) is iOS/Mac Catalyst only
if (DeviceInfo.Platform == DevicePlatform.Android ||
DeviceInfo.Platform == DevicePlatform.WinUI)
{
MultiTouchSection.IsVisible = false;
}
}

void OnBoxTapped(object? sender, TappedEventArgs e)
{
if (BindingContext is LongPressViewModel vm)
{
vm.OnBoxTapped();
}
}

// <docregion_longpressed_handler>
void OnLongPressed(object? sender, LongPressedEventArgs e)
{
if (BindingContext is LongPressViewModel vm)
{
var position = e.GetPosition(InteractiveBox);
vm.PositionText = position.HasValue
? $"Position: ({position.Value.X:F0}, {position.Value.Y:F0})"
: "Position: unavailable";
}
}
// </docregion_longpressed_handler>

// <docregion_longpressing_handler>
void OnLongPressing(object? sender, LongPressingEventArgs e)
{
if (BindingContext is LongPressViewModel vm)
{
vm.LongPressState = e.Status switch
{
GestureStatus.Started => "Status: Started — hold steady...",
GestureStatus.Running => "Status: Running — still holding...",
GestureStatus.Completed => "Status: Completed — gesture complete!",
GestureStatus.Canceled => "Status: Canceled — gesture aborted",
_ => $"Status: {e.Status}"
};

var position = e.GetPosition(InteractiveBox);
if (position.HasValue)
vm.PositionText = $"Position: ({position.Value.X:F0}, {position.Value.Y:F0})";
}
}
// </docregion_longpressing_handler>

void OnMultiTouchLongPressed(object? sender, LongPressedEventArgs e)
{
MultiTouchStatus.Text = "Two-finger long press detected!";
MultiTouchBox.Color = Colors.Orange;
}

async void OnImageTapped(object? sender, TappedEventArgs e)
{
await DisplayAlertAsync("Tap Detected", "You tapped the .NET bot!", "OK");
}

void OnImageLongPressed(object? sender, LongPressedEventArgs e)
{
if (BindingContext is LongPressViewModel vm)
{
var position = e.GetPosition(sender as Element);
vm.ImageStatus = position.HasValue
? $"✅ Long pressed at ({position.Value.X:F0}, {position.Value.Y:F0})"
: "✅ Long press detected!";
}
}
}
Loading
Loading