0

I have a border in MVVM. What I am trying to achieve is to detect mouse left button down outside the border and then hide it. I can do it within the MouseLeftButtonDown event for main window, but I do not know if it is the best solution. How could I do this? I want to avoid this click to interfere with other events, for example, this border is placed in a stackpanel and the stackpanel is being hidden on mouse left button double click.

<Border Grid.Row="2" 
     x:Name="customPopup" 
     CornerRadius="10,10,0,0" 
     Height="25" Margin="0"
     HorizontalAlignment="Center" 
     VerticalAlignment="Center"
     Width="Auto"
     BorderBrush="DarkBlue" 
     BorderThickness="1"  
     Background="AntiqueWhite">
    <StackPanel  Orientation="Horizontal" 
                 HorizontalAlignment="Center">
        <Image Source="/Common.Images;component/Images/Info.png" 
               Height="20" 
               Width="20" Stretch="Fill"/>
        <TextBlock Margin="5" 
                   VerticalAlignment="Center" 
                   HorizontalAlignment="Left" 
                   Background="Transparent" 
                   FontSize="12">
                  <Run Text="Click outside to close it"/>
        </TextBlock>
    </StackPanel>
</Border>
Willy
  • 9,848
  • 22
  • 141
  • 284

1 Answers1

0

Using MouseDown on the window is probably your best bet to get your desired results. You'll need to do some calculations in order to see if the cursor is outside of the border. Something like:

private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
    // get positions
    Point mouseLoc = Mouse.GetPosition(null);
    Point borderLoc = customPopup.TranslatePoint(new Point(0,0), null);

    // check if the mouse is outside the border
    if((mouseLoc.X < borderLoc.x || mouseLoc.X > (borderLoc.X + customPopup.ActualWidth)) && (mouseLoc.Y < borderLoc.Y || mouseLoc.Y > borderloc.Y + customPopup.ActualHeight))
    {
        // hide the border
    }
}

Then to handle the double click, use PreviewMouseDoubleClick. Since Preview events are tunneling rather than bubbling, the double click should get called even if you have a single click event on the same element.

private void Window_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
     // double click code...
     e.Handled = true;
}
Matt L.
  • 748
  • 5
  • 20
  • I have not seen any method with the signature you post. There is the following signature: private void Window_PreviewMouseDown(object sender, MouseButtonEventArgs e) Also it is not working since my double click event (which hides the stackpanel) is not working then. – Willy Jul 25 '17 at 18:10
  • Got my tunneling/bubbling events mixed up, check my edit – Matt L. Jul 25 '17 at 18:18
  • Within Window_MouseDown, you use && and it should be ||. Also when clicking outside custom popup not always it is being hidden, for example, If I click on a button or whithin a Textbox, then popup is not being hidden. I would like to be hidden when clicking on any control in the UI outside the popup. How can I solve this? – Willy Jul 26 '17 at 07:49
  • For the calculation of if the cursor is outside the border, you need the && because you need to be sure both the X and Y values are outside the border, not just one or the other. As for the event not firing, the click events for the button or textbox are probably being handled somewhere else. Check out this post talking about tunneling vs. bubbling events, as that is what your issue is https://stackoverflow.com/questions/16736444/difference-between-bubbling-and-tunneling-events – Matt L. Jul 26 '17 at 13:57