简体   繁体   中英

WPF Popup's alignment point inconsistent (top right, or top left) with Placement=AbsolutePoint

I am seeing inconsistent placement of my Popup control when my application is run on different computers. I have the Placement set to AbsolutePoint and experience the popup being aligned to popup's top right on 2 computers, but to the popup's top left on 1 other computer (when running the same application on each computer).

I am positioning the popup using the HorizontalOffset and VerticalOffset dependency properties, relative to the screen's top left coordinate.

The documentation ( https://msdn.microsoft.com/en-us/library/bb613596%28v=vs.110%29.aspx ) shows that the popup alignment point should be to the top left of the popup, with the target area being the whole screen (and so target origin in the top left of the screen).

Thinking that it might be a change in the .Net framework or a difference in display scaling factors (unlikely, but still), I gathered the following info, but I cannot see an obvious reason for this behaviour;

The computers where the popup alignment point is to the popup's top right are: 1).Net Framework 4.5.1 and scaling factor of 125% 2).Net Framework 4.5.2 and scaling factor of 100%

The computer where the popup alignment point is to the popup's top left is: 1).Net Framework 4.5.2 with an unknown scaling factor (I need access to it to check again).

Any ideas why the placement is inconsistent? It is not to do with the screen's boundaries - the popup is not near any edge.

I fixed this issue by adding a border in the same grid col/row as the desired placement target. Then set this as the placement target instead. By binding the width of this border to the popup content it will adjust it's width automatically therefore the alignment (left or right) is irrelevant. If you want to still control alignment, you can do that by aligning the placement target border. Hope that makes sense, if not, here is a quick example.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Popup x:Name="StartMenuPopup" Placement="Top" PlacementTarget="{Binding ElementName=PopupTarget}" >
        <Border x:Name="PopupBorder">
        </Border>
    </Popup>

    <Border x:Name="PopupTarget" Grid.Row="1" Width="{Binding ActualWidth, Mode=OneWay, ElementName=PopupBorder}" 
    BorderThickness="0" HorizontalAlignment="Left" VerticalAlignment="Top"/>

    <startmenu:TaskBar Grid.Row="1">
        <startmenu:TaskBar.StartButton>
            <startmenu:ToggleMenu Width="36" x:Name="StartButton"
                          ImageData="{Binding StartButtonImageData}"
                          AssociatedPopup="{Binding ElementName=StartMenuPopup}"
                          IsOpen="{Binding StartMenuOpen, Mode=TwoWay}"/>
        </startmenu:TaskBar.StartButton>
    </startmenu:TaskBar>
</Grid>

The popup PlacementTarget binds to the PopupTarget border, and the PopupTarget border width binds back to the PopupBorder element. This makes the PopupTarget border the same width as the popup therefore negating the alignment issue.

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