6
votes

If I change StaysOpen to "True", the popup shows up, but it doesn't close when you click outside of it, so that's not what I want.

Here is the relevant XAML code:

<Border x:Name="popupPlacementTarget">
    <i:Interaction.Behaviors>
        <local:PopupBehavior>
            <local:PopupBehavior.Popup>
                <Popup PlacementTarget="{Binding ElementName=popupPlacementTarget}"
                       Placement="MousePoint"
                       StaysOpen="False">
                    <ContentPresenter Content="{Binding SomeContent}" ContentTemplate="{StaticResource SomeContentTemplate}" />
                </Popup>
            <local:PopupBehavior.Popup>
        </local:PopupBehavior>
    </i:Interaction.Behaviors>
</Border>

And here is the PopupBehavior code:

public class PopupBehavior : Behavior<UIElement>
{
    #region Dependency Properties

    public static readonly DependencyProperty PopupProperty = DependencyProperty.Register(
        "Popup", typeof(Popup), typeof(PopupBehavior), new FrameworkPropertyMetadata(default(Popup)));

    #endregion Dependency Properties

    #region Properties

    public Popup Popup
    {
        get { return (Popup)this.GetValue(PopupProperty); }
        set { this.SetValue(PopupProperty, value); }
    }

    #endregion Properties

    #region Protected Methods

    protected override void OnAttached()
    {
        base.OnAttached();

        this.AssociatedObject.MouseDown += this.OnMouseDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        this.AssociatedObject.MouseDown -= this.OnMouseDown;
    }

    #endregion Protected Methods

    #region Private Methods

    private void OnMouseDown(object sender, MouseButtonEventArgs eventArgs)
    {
        var popup = this.Popup;
        if (popup == null)
        {
            return;
        }

        this.Popup.IsOpen = true;
    }

    #endregion Private Methods
}

Any idea why my popup won't show up with StaysOpen="False"?

1
possible duplicate of StayOpen="False" with inherited popups. Please see my answer from this linked question for a solution to your problem. - Sheridan
I do not feel like the answer to the question you linked is applicable to this question. - Kelsie
Is your posted xaml complete? Currently it looks like you're adding the Behavior as a child to the Border than within <i:Interaction.Behaviors>...</i:Interaction.Behaviors> - Viv
That's a typo, it is within interaction behaviors. I'll edit. - Kelsie
@Kelsie, it is rare that you get a question that is exactly the same as another. The point is that there is a working solution for you in the linked post, if you would only just try it. - Sheridan

1 Answers

1
votes

It turns out there was an ancestor that was indiscriminately grabbing capture on mouse down. Everything is working correctly now that I've corrected this issue.

As an aside, I was able to hack around this problem by setting StaysOpen="True", inheriting Popup, and hooking in to the global mouse events within the derived Popup. When the popup opens, I'd attach the handler to the global input events. Then, when an event is received, I'd filter it such that I'm only responding to left mouse button down events. In handling this event, I'd close the popup and detach the event if the mouse is not hovering the popup. It worked, but it is obviously a dirty hack, and I'm happy that I got this working without it.