views:

2671

answers:

5

I have a Popup defined like this:

        <Popup
            Name="myPopup"
            StaysOpen="True"
            Placement="Bottom"
            PlacementRectangle="0,20,0,20"
            PlacementTarget="{Binding ElementName=myPopupAnchor}">
            <TextBlock ... />
        </Popup>

I have added event handlers to the myPopupAnchor for the events MouseEnter and MouseLeave. The two event handlers toggles the popups visibility.

My problem is the position of myPopupAnchor is only read when the popup is first shown, or hidden and then shown again. If the anchor moves, the popup does not.

Im Looking for ways to work around this, I want a moving Popup. Can I notify WPF that the PlacementTarget binding has changed and should be read again? Can I manually set the popups position?

Currently, I have a very crude workaround that involves closing and then opening the popup again, which causes some repainting issues.

A: 

You can not do this. When Popup is displayed on the screen, it does not reposition itself if its parent is repositioned. Thats the behavior of Popup control. check this: http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.popup.aspx

you can use a Window(with WindowStyle=None) instead of Popup that may solve your problem.

viky
Understood, thanks, Ill look into workarounds.
mizipzor
+1  A: 

Download the Popup Popup Position Sample at:

http://msdn.microsoft.com/en-us/library/ms771746(VS.85).aspx

The code sample uses the class CustomPopupPlacement with a Rect object, and binds to horizontal and vertical offsets to move the Popup.

<Popup Name="popup1" Placement="Bottom" AllowsTransparency="True"
       IsOpen="{Binding ElementName=popupOpen, Path=IsChecked}"
       HorizontalOffset="{Binding ElementName=HOffset, Path=Value, Mode=TwoWay}"
       VerticalOffset="{Binding ElementName=VOffset, Path=Value, Mode=TwoWay}"
Zamboni
Is the popup moved when the properties changed? Or are they just read when the popup is initially displayed?
mizipzor
the popup moves.download the sample, and give it a try.
Zamboni
I tried this sample, but it does not appear to move the Popup when the window is moved.
NathanAW
A: 

I looked at a couple options and samples out there. The thing that seems to work best for me is to "bump" one of the properties that causes the Popup to reposition itself on its own. The property that I used is HorizontalOffset.

I set it to (itself + 1) and then set it back the original value. I do this in an event handler that runs when the window is repositioned.

// Reference to the PlacementTarget.
DependencyObject myPopupPlacementTarget;

// Reference to the popup.
Popup myPopup; 

Window w = Window.GetWindow(myPopupPlacementTarget);
if (null != w)
{
    w.LocationChanged += delegate(object sender, EventArgs args)
    {
        var offset = myPopup.HorizontalOffset;
        myPopup.HorizontalOffset = offset + 1;
        myPopup.HorizontalOffset = offset;
    };
}

When the window is moved, the popup will reposition. The subtle change in the HorizontalOffset is not noticed because the window and popup are already moving anyway.

I'm still evaluating whether a popup control is the best option in cases where the control stays open during other interaction. I'm thinking that Ray Burns suggestion to put this stuff in an Adorner layer seems like a good approach for some scenarios.

NathanAW
A: 

But what triggers "w.LocationChanged"?

nlf
A: 

If you want to move the popup, there is a simple trick : change its position,then set :

IsOpen = false;
IsOpen = true;
Aurélien Ribon