Dragging a window in WPF using DragMove method and click handler on the same button

只谈情不闲聊 提交于 2019-12-13 04:09:16

问题


I need a button for two purposes:
- Users can drag the application's window using the button
- Users can simply click the button to toggle visibility of some other element in the window.

The button is a PNG image.

I am trying to do it in the following way:

XAML:

<Button Name="toggleButton" Click="toggleButton_Click" Canvas.Left="177" Canvas.Top="0">
  <Button.Template>
    <ControlTemplate>
      <Image Source="/FootballRssReader;component/images/ball.png" MouseLeftButtonDown="toggleButton_MouseLeftButtonDown"/>
    </ControlTemplate>
  </Button.Template>
</Button>

C#:

 private void toggleButton_Click(object sender, RoutedEventArgs e)
        {
            contentVisible = !contentVisible;
            content.Visibility = contentVisible ? Visibility.Visible : Visibility.Collapsed;
        }

 private void toggleButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DragMove();
        }

The problem is that only the window moving works. Clicks on the button don't invoke the Click event handler. When I remove MouseLeftButtonDown event handling from the button's image, the Click event is executed.

Can anybody help me? Is it possible to create such a button?

I tried setting Handled to false in the Image but it didn't help.

Thanks, Michal


回答1:


DragMove starts a modal message loop and doesn't return until the mouse button is released, so by the time the button receives the MouseLeftButtonDown event it's already lost the chance to click.

I'm assuming you don't want the Click to happen if the user drags the window. One approach is to do something similar to drag-drop, and only call DragMove if the mouse starts moving while it is pressed. Attach handlers to PreviewMouseLeftButtonDown and PreviewMouseMove on the Button:

<Button Name="toggleButton" Click="toggleButton_Click"
    Canvas.Left="177" Canvas.Top="0"
    PreviewMouseMove="toggleButton_PreviewMouseMove"
    PreviewMouseLeftButtonDown="toggleButton_PreviewMouseLeftButtonDown">
    <Button.Template>
        <ControlTemplate>
            <Image Source="/FootballRssReader;component/images/ball.png"/>
        </ControlTemplate>
    </Button.Template>
</Button>

Record the mouse position in the PreviewLeftMouseButtonDown handler, and then start the DragMove in the PreviewMouseMove handler if the mouse has started moving:

private Point startPoint;

private void toggleButton_PreviewMouseLeftButtonDown(
    object sender, MouseButtonEventArgs e)
{
    startPoint = e.GetPosition(toggleButton);
}

private void toggleButton_PreviewMouseMove(object sender, MouseEventArgs e)
{
    var currentPoint = e.GetPosition(toggleButton);
    if (e.LeftButton == MouseButtonState.Pressed &&
        toggleButton.IsMouseCaptured &&
        (Math.Abs(currentPoint.X - startPoint.X) >
            SystemParameters.MinimumHorizontalDragDistance ||
        Math.Abs(currentPoint.Y - startPoint.Y) >
            SystemParameters.MinimumVerticalDragDistance))
    {
        // Prevent Click from firing
        toggleButton.ReleaseMouseCapture();
        DragMove();
    }
}


来源:https://stackoverflow.com/questions/3592488/dragging-a-window-in-wpf-using-dragmove-method-and-click-handler-on-the-same-but

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!