简体   繁体   中英

How to set the popup control hide automatically in WPF?

在此处输入图片说明 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;
    }

}

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM