views:

23

answers:

1

Hi,

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

A: 

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