I have a borderless, transparent Window
with only one Button
.
My fancy button looks like this
The expected behaviour is:
- When I click and drag the Button, the Button must follow the cursor.
- When I only click on the Button, the MouseDown, PreviewMouseDown events or Command binding should raise.
At first I tried to call the DragMove() on PreviewMouseDown event, but that blocks the click events. Now my idea is: I set a 100ms delay after mouse down. If the time passed, than the button wil be dragging, otherwise it was just a click.
Code
private bool _dragging;
private Point startpos;
CancellationTokenSource cancellation;
private void Button_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (_dragging && e.LeftButton == MouseButtonState.Pressed)
{
var currentpos = e.GetPosition(this);
Left += currentpos.X - startpos.X;
Top += currentpos.Y - startpos.Y;
}
}
private async void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton != MouseButton.Left)
return;
_dragging = false;
startpos = e.GetPosition(this);
cancellation?.Cancel();
cancellation = new CancellationTokenSource();
await Task.Delay(100, cancellation.Token).ContinueWith(task =>
{
_dragging = !task.IsCanceled;
});
}
private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
if (_dragging)
{
_dragging = false;
e.Handled = true;
}
cancellation?.Cancel();
}
Basically it works, but has some bugs:
- When I hold down the mouse button for longer time and release, then the click won't work, because after 100ms the dragging will be active.
- After I dragged the button, and click anywhere outside the
Button
andWindow
control, the PreviewMouseDown and PreviewMouseUp events are raised. I don't know why??
Does somebody have any better solution?