Implementing Draggable Regions in WPF Applications

To enable draggable functionality for UI elements in WPF, you need to handle three core mouse events: mouse press, release, and movement. When the mouse button is presed, capture the initial state and coordinates. During mouse movement, calculate the offset from the starting position and update the element's location according. Release the drag operation when the mouse button is lifted.

This implementation uses a Grid container as the dragging enviroment. The approach involves capturing the control's Margin property and the mouse position relative to the parent container when dragging begins. As the mouse moves, the system calculates the positional difference and updates the control's Margin to reflect its new location.

Interface Structure:

<Grid x:Name="MainContainer">
    <wpf:ChromiumWebBrowser x:Name="WebView" RenderOptions.BitmapScalingMode="HighQuality"/>
    <Grid x:Name="DraggablePanel" Width="40" Height="80" Opacity="0.8"
          HorizontalAlignment="Left" VerticalAlignment="Top"
          PreviewMouseLeftButtonDown="HandleMouseDown"
          PreviewMouseLeftButtonUp="HandleMouseUp"
          PreviewMouseMove="HandleMouseMove">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Width="40" Height="40" Padding="-10" ToolTip="Refresh"
                Click="RefreshClicked">
            <TextBlock Style="{StaticResource IconFontStyle}" Text="" FontSize="26"/>
        </Button>
        <Button Grid.Row="1" Width="40" Height="40" ToolTip="Move" Padding="-10">
            <TextBlock Style="{StaticResource IconFontStyle}" Text="" FontSize="26"/>
        </Button>
    </Grid>
</Grid>

Event Handling Logic:

private bool IsDraggingEnabled;
private Thickness InitialMargin;
private Point StartingPoint;

private void HandleMouseDown(object sender, MouseButtonEventArgs e)
{
    IsDraggingEnabled = true;
    StartingPoint = e.GetPosition(MainContainer);
    InitialMargin = DraggablePanel.Margin;
}

private void HandleMouseUp(object sender, MouseButtonEventArgs e)
{
    IsDraggingEnabled = false;
}

private void HandleMouseMove(object sender, MouseEventArgs e)
{
    if (!IsDraggingEnabled) return;

    var currentPoint = e.GetPosition(MainContainer);
    var deltaX = currentPoint.X - StartingPoint.X;
    var deltaY = currentPoint.Y - StartingPoint.Y;
    
    var newLeft = InitialMargin.Left + deltaX;
    var newTop = InitialMargin.Top + deltaY;
    
    // Prevent negative positioning
    newLeft = Math.Max(newLeft, 0);
    newTop = Math.Max(newTop, 0);
    
    DraggablePanel.Margin = new Thickness(
        newLeft, 
        newTop, 
        InitialMargin.Right, 
        InitialMargin.Bottom
    );
}

Tags: WPF XAML .NET UI Development Mouse Events

Posted on Sat, 08 Aug 2026 16:28:14 +0000 by fazbob