Перетаскивание окна в WPF с помощью метода DragMove и нажатие на обработчик на той же кнопке - PullRequest
0 голосов
/ 29 августа 2010

Мне нужна кнопка для двух целей:
- Пользователи могут перетаскивать окно приложения с помощью кнопки
- Пользователи могут просто нажать кнопку, чтобы переключить видимость какого-либо другого элемента в окне.

Кнопка представляет собой изображение в формате PNG.

Я пытаюсь сделать это следующим образом:

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();
        }

Проблема в том, что работает только перемещение окна. Клики по кнопке не вызывают обработчик события Click. Когда я удаляю обработку события MouseLeftButtonDown из изображения кнопки, событие Click выполняется.

Кто-нибудь может мне помочь? Можно ли создать такую ​​кнопку?

Я попытался установить для параметра Handled значение false в изображении, но это не помогло.

Спасибо, Михал

1 Ответ

8 голосов
/ 29 августа 2010

DragMove запускает модальный цикл сообщений и не возвращается, пока кнопка мыши не будет отпущена, поэтому к тому времени, когда кнопка получает событие MouseLeftButtonDown, она уже потеряла шанс щелкнуть.

Я предполагаю, что вы не хотите, чтобы щелчок происходил, если пользователь перетаскивает окно. Один из подходов состоит в том, чтобы сделать что-то похожее на drag-drop, и вызывать DragMove только в том случае, если мышь начинает двигаться, пока она нажата. Прикрепите обработчики к PreviewMouseLeftButtonDown и PreviewMouseMove на кнопке:

<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>

Запишите положение мыши в обработчике PreviewLeftMouseButtonDown, а затем запустите DragMove в обработчике PreviewMouseMove, если мышь начала двигаться:

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();
    }
}
...