Abstract
Swipe gestures have become a fundamental interaction pattern in modern mobile and touch-enabled applications. This proposal provides enhancements to the Swipe control that wraps content and reveals contextual actions through swipe gestures, following established patterns.
Requisites
- Any direction: Container control that reveals swipe items through directional gestures (left, right, up, down)
- Support for both single items and collections of swipe items per direction
- Programmatic control over swipe state (open/close) in addition to gesture-driven interaction
- Events for swipe lifecycle (opening, opened, closing, closed)
- Platform-appropriate swipe thresholds and animation behaviors
API
/// <summary>
/// Represents a container control that wraps content and reveals swipe items through directional gestures.
/// </summary>
public class Swipe : ContentControl
{
/// <summary>
/// Gets or sets the swipe items displayed when swiping from left to right.
/// </summary>
public DataTemplate Left { get; set; }
/// <summary>
/// Gets or sets the swipe items displayed when swiping from right to left.
/// </summary>
public DataTemplate Right{ get; set; }
/// <summary>
/// Gets or sets the swipe items displayed when swiping from top to bottom.
/// </summary>
public DataTemplate Top { get; set; }
/// <summary>
/// Gets or sets the swipe items displayed when swiping from bottom to top.
/// </summary>
public DataTemplate Bottom { get; set; }
/// <summary>
/// Gets or sets the swipe threshold value (0.0 to 1.0) at which swipe items transition to execute/reveal state.
/// Default is 0.5 (50% of available space).
/// </summary>
public double Threshold { get; set; }
/// <summary>
/// Programmatically opens the swipe view in the specified direction.
/// </summary>
/// <param name="openSwipeItem">The direction to open.</param>
public void Open(OpenSwipeItem openSwipeItem);
/// <summary>
/// Programmatically closes any currently open swipe items.
/// </summary>
public void Close();
/// <summary>
/// Occurs when a swipe gesture begins and swipe items start to be revealed.
/// </summary>
public event EventHandler<SwipeStartedEventArgs>? SwipeStarted;
/// <summary>
/// Occurs when swipe items are being revealed during the gesture (continuous updates).
/// </summary>
public event EventHandler<SwipeChangingEventArgs>? SwipeChanging;
/// <summary>
/// Occurs when the swipe gesture ends and swipe items transition to their final state (fully open or closed).
/// </summary>
public event EventHandler<SwipeEndedEventArgs>? SwipeEnded;
/// <summary>
/// Occurs when a SwipeItem is invoked (tapped or executed via threshold).
/// </summary>
public event EventHandler<SwipeItemInvokedEventArgs>? SwipeItemInvoked;
}
/// <summary>
/// Represents a collection of SwipeItem objects displayed in a SwipeView.
/// </summary>
public class SwipeItems : AvaloniaList<SwipeItem>
{
/// <summary>
/// Gets or sets the behavior mode for this collection of swipe items.
/// </summary>
public SwipeMode Mode { get; set; }
/// <summary>
/// Gets or sets how the swipe items are presented visually.
/// </summary>
public SwipeBehaviorOnInvoked SwipeBehaviorOnInvoked { get; set; }
}
/// <summary>
/// Specifies the interaction mode for swipe items.
/// </summary>
public enum SwipeMode
{
/// <summary>
/// Swipe items are revealed and remain visible for user selection.
/// User must tap a swipe item to invoke it.
/// </summary>
Reveal = 0,
/// <summary>
/// When swipe threshold is reached, the first swipe item is executed automatically
/// without requiring an additional tap.
/// </summary>
Execute = 1
}
/// <summary>
/// Specifies the behavior when a swipe item is invoked.
/// </summary>
public enum SwipeBehaviorOnInvoked
{
/// <summary>
/// The swipe view automatically closes after the item is invoked.
/// </summary>
Auto = 0,
/// <summary>
/// The swipe view closes after the item is invoked.
/// </summary>
Close = 1,
/// <summary>
/// The swipe view remains open after the item is invoked.
/// </summary>
RemainOpen = 2
}
/// <summary>
/// Specifies which swipe items to open programmatically.
/// </summary>
public enum OpenSwipeItem
{
/// <summary>
/// Open the left swipe items.
/// </summary>
Left = 0,
/// <summary>
/// Open the right swipe items.
/// </summary>
Right = 1,
/// <summary>
/// Open the top swipe items.
/// </summary>
Top = 2,
/// <summary>
/// Open the bottom swipe items.
/// </summary>
Bottom = 3
}
Usage Examples
Programmatic Open/Close
<labs:Swipe x:Name="DemoSwipe"
OpenRequested="DemoSwipe_OpenRequested"
CloseRequested="DemoSwipe_CloseRequested"
Margin="10">
<labs:Swipe.Content>
<Border Background="LightGray" Padding="16" CornerRadius="4">
<TextBlock Text="Swipe or use buttons below" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</labs:Swipe.Content>
<labs:Swipe.Right>
<DataTemplate>
<Border Background="Blue" Width="48" Height="48" CornerRadius="4">
<TextBlock Text="R" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</DataTemplate>
</labs:Swipe.Right>
<labs:Swipe.Left>
<DataTemplate>
<Border Background="Green" Width="48" Height="48" CornerRadius="4">
<TextBlock Text="L" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</DataTemplate>
</labs:Swipe.Left>
</labs:Swipe>
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="5" Margin="5">
<Button Content="Open Left" Click="OpenLeft" Width="80" />
<Button Content="Open Right" Click="OpenRight" Width="80" />
<Button Content="Close" Click="CloseSwipe" Width="60" />
</WrapPanel>
Swipe List
<ItemsControl ItemsSource="{Binding Items}" Margin="5">
<ItemsControl.ItemTemplate>
<DataTemplate>
<labs:Swipe Margin="2">
<labs:Swipe.Content>
<Border Background="LightCoral" Padding="10">
<TextBlock Text="{Binding Name}" />
</Border>
</labs:Swipe.Content>
<labs:Swipe.Right>
<DataTemplate>
<Border Background="Blue" Width="48" Height="48" CornerRadius="4" />
</DataTemplate>
</labs:Swipe.Right>
<labs:Swipe.Left>
<DataTemplate>
<Border Background="Green" Width="48" Height="48" CornerRadius="4" />
</DataTemplate>
</labs:Swipe.Left>
</labs:Swipe>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Summary
Requested changes:
- Add explicit properties for Left, Right, Top, and Bottom swipe templates as IDataTemplate? to fully support all swipe directions with customizable content.
- Add Threshold controls how far the user must swipe before the swipe items snap open or execute.
- Introduce a SwipeDirection enum to cleanly specify directions in API methods and events.
- Add Open(SwipeDirection direction) and Close() methods for programmatic control of swipe states, enabling external logic to open or close the swipe area in any direction.
- Add OpenRequested and CloseRequested events to signal when swipe actions start or end, both via gesture and programmatic commands.
Abstract
Swipe gestures have become a fundamental interaction pattern in modern mobile and touch-enabled applications. This proposal provides enhancements to the Swipe control that wraps content and reveals contextual actions through swipe gestures, following established patterns.
Requisites
API
Usage Examples
Programmatic Open/Close
Swipe List
Summary
Requested changes: