Prince
Prince

Reputation: 199

How to set the popup control hide automatically in WPF?

enter image description here As shown in the picture, i want the "one" popup control show when the mouse enter into the ButtonOne button. When I move the mouse from ButtonOne to Button Two, The "One" popup control hides and "Two" shows. When the mouse isn't over the button or popup, the popup control hide automatically.

I've tried to use mouse_enter and mouse_leave event, but when the mouse is over the button and moving, the popup control twinkle. When the mouse is not over the button or popup control, the popup control doesn't hide.

So, How to solve this problem?

XAML:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel>
        <Button Name="ButtonOne" Height="100" Width="100" HorizontalAlignment="Left" MouseEnter="Button_MouseEnter" MouseLeave="ButtonOne_MouseLeave">Button One</Button>
        <Button Name="ButtonTwo" Height="100" Width="100" HorizontalAlignment="Left" MouseEnter="Button_MouseEnter_1" MouseLeave="ButtonTwo_MouseLeave">Button Two</Button>
        <Popup Name="Pop1" StaysOpen="False" Placement="Right" PlacementTarget="{Binding ElementName=ButtonOne}" PopupAnimation="Fade" AllowsTransparency="True" MouseEnter="Pop1_MouseEnter" MouseLeave="Pop1_MouseLeave">
            <Border BorderBrush="Beige" BorderThickness="2" Background="White">
                <StackPanel>
                    <TextBlock Text="One"></TextBlock>
                    <Button Content="OneManagement"></Button>
                </StackPanel>
            </Border>
        </Popup>
        <Popup Name="Pop2" StaysOpen="False" Placement="Right" PlacementTarget="{Binding ElementName=ButtonTwo}"  PopupAnimation="Fade" AllowsTransparency="True">
            <Border BorderBrush="Beige" BorderThickness="2" Background="White">
                <StackPanel>
                    <TextBlock Text="Two"></TextBlock>
                    <Button Content="TwoManangement"></Button>
                </StackPanel>
            </Border>
        </Popup>
    </StackPanel>
</Grid>

Code Behind:

    public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_MouseEnter(object sender, MouseEventArgs e)
    {
        Pop2.IsOpen = false;
        Pop1.IsOpen = true;
    }

    private void Button_MouseEnter_1(object sender, MouseEventArgs e)
    {
        Pop1.IsOpen = false;
        Pop2.IsOpen = true;
    }


    private void ButtonOne_MouseLeave(object sender, MouseEventArgs e)
    {
        Pop1.IsOpen = false;
    }

    private void ButtonTwo_MouseLeave(object sender, MouseEventArgs e)
    {
        Pop2.IsOpen = false;
    }

    private void Pop1_MouseEnter(object sender, MouseEventArgs e)
    {
        Pop1.IsOpen = true;
    }

    private void Pop1_MouseLeave(object sender, MouseEventArgs e)
    {
        Pop1.IsOpen = false;
    }

}

Upvotes: 1

Views: 5198

Answers (2)

Ignatius
Ignatius

Reputation: 1177

If you set your Pop1 StaysOpen property to False, the moment the popup opens, the MouseLeave event of ButtonOne is triggered, even if the mouse is actually still over the button. Afterwards while the popup is still in open state your buttons will no longer trigger the MouseEnter and MouseLeave events. This is because when StaysOpen is false, the Popup control intercepts all mouse and keyboard events to determine when one of these events occurs outside the Popup control.

Therefore, you can set the popups' StaysOpen property to True:

<Popup Name="Pop1" StaysOpen="True" ...
<Popup Name="Pop2" StaysOpen="True" ...

Then, your buttons' MouseLeave event handlers can check the position where the mouse leaves:

private void ButtonOne_MouseLeave(object sender, MouseEventArgs e)
{
    Point leavePoint = e.GetPosition(ButtonOne);
    if (leavePoint.X < ButtonOne.ActualWidth)
    {
        Pop1.IsOpen = false;
    }
}

private void ButtonTwo_MouseLeave(object sender, MouseEventArgs e)
{
    Point leavePoint = e.GetPosition(ButtonTwo);
    if (leavePoint.X < ButtonTwo.ActualWidth)
    {
        Pop2.IsOpen = false;
    }
}

By checking the leave position, we only close the popup if the mouse leave the button through other location other than the location of the popup (which in this case is on the right side of the button). In other words, for this case, we want the popup to close when the mouse leaves the button from the top, left, and bottom side, but we want to keep the popup open if the mouse leaves the button from the right side.

Subsequently, we can use a similar logic with the popups MouseLeave event handlers:

private void Pop1_MouseLeave(object sender, MouseEventArgs e)
{
    Point leavePoint = e.GetPosition(ButtonOne);
    if (leavePoint.X > ButtonOne.ActualWidth)
    {
        Pop1.IsOpen = false;
    }
}

private void Pop2_MouseLeave(object sender, MouseEventArgs e)
{
    Point leavePoint = e.GetPosition(ButtonTwo);
    if (leavePoint.X > ButtonTwo.ActualWidth)
    {
        Pop2.IsOpen = false;
    }
}

Upvotes: 1

sujith karivelil
sujith karivelil

Reputation: 29006

Better to use StaysOpen="False" then the popup will automatically closed when the focus is lost. you can use like the following

<Popup x:Name="myPopUp" StaysOpen="False">

Upvotes: 1

Related Questions