Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to stop a WPF Popup from repositioning itself when it goes off-screen?

Is there any way to stop a WPF Popup from repositioning itself when it goes off-screen?

I found this old question, but it didn't get a proper answer to it. Is there any way to do this? I'm willing to subclass it if necessary. Thanks.

like image 555
Rich Avatar asked Jan 08 '11 04:01

Rich


People also ask

How do I keep windows on top of WPF?

Basically, to keep it on top you just set the lose focus event to make it go back to top.

How do I pop a window in WPF?

First, in window. xaml we will define a button and pass the values to it's Click property that is the name of the event generated on the clicking of the Show popup button. Here two grids are used, one inside the other. The other grid contains the ellipse with color filled and a button showing the Hide text on it.

What is Popup in WPF?

Advertisements. Popup is a control that displays content on top of existing content, within the bounds of the application window. It is a temporary display on other content.


1 Answers

As Andrei points out, this behavior is deep inside the Popup control and hard to overcome. If you are willing to do some work it can be done by resizing and translating the content of the popup when it reaches the screen edges. For the purposes of the demonstration, we'll focus on the left edge of the screen.

If we have some XAML like this:

<Window ...
        LocationChanged="Window_LocationChanged"
        SizeChanged="Window_SizeChanged"
        >
    <Grid>
        <Rectangle Name="rectangle1" Width="100" Height="100" Fill="Blue"/>
        <Popup Name="popup1" PlacementTarget="{Binding ElementName=rectangle1}" IsOpen="True" Width="100" Height="100">
            <TextBlock Background="White" TextWrapping="Wrap" Width="100" Height="100">
                <TextBlock.Text>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</TextBlock.Text>
            </TextBlock>
        </Popup>
    </Grid>
</Window>

and code-behind like this:

private void Window_LocationChanged(object sender, EventArgs e)
{
    RefreshPopupPosition();
}

private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
    RefreshPopupPosition();
}

private void RefreshPopupPosition()
{
    var upperLeft = rectangle1.PointToScreen(new Point(0, 100));
    var xOffset = Math.Min(0, upperLeft.X);
    popup1.Width = xOffset + 100;
    (popup1.Child as FrameworkElement).Margin = new Thickness(xOffset, 0, 0, 0);
    popup1.HorizontalOffset += 1;
    popup1.HorizontalOffset -= 1;
}

then by calculating that the Popup would be off-screen, we can reduce the width of the content and give it a negative margin so that the portion that is on-screen is clipped to what would have appeared if the Popup were to allow this.

This would have to be extended to deal with all four edges of the screen and the possibility of multiple screens, but it demonstrates that the approach is workable.

like image 83
Rick Sladkey Avatar answered Oct 08 '22 03:10

Rick Sladkey