Getting Actual Placement of a Flyout

2019-08-27 04:02发布

I have a flyout that appears near the cursor when a particular user input is triggered.

According to the docs, the Flyout.Placement property is only a preference and does not necessarily reflect the position of the flyout.

I expect the framework to call GetFlyoutPlacement to determine the actual placement. I want to know what the actual placement is so that I can add a little arrow pointing at the cursor position, something like shown in the following:

popup with pointer

Is my only option to make the call to GetFlyoutPlacement myself (triggered on the Flyout.Opening event), or is there some more convenient way to do this?

2条回答
Root(大扎)
2楼-- · 2019-08-27 04:39

Checkout the approach I suggested here. I believe it is better, because instead of guessing the internal placement algorithm it just compares the absolute coordinates of the flyout and the target element.

查看更多
不美不萌又怎样
3楼-- · 2019-08-27 04:48

My calls on GetFlyoutPlacement and GetFlyoutPlacementTargetInfo resulted in Error HRESULT E_FAIL has been returned from a call to a COM component. which didn't leave me very much to go on, so I just ended up implementing what I imagine is the logic behind those functions:

public static FlyoutPlacementMode GetActualFlyoutPlacement(
    Rect placementTarget,
    Size flyoutSize,
    FlyoutPlacementMode preferredPlacement )
{
    Rect ViewArea = Window.Current.Bounds;
    ViewArea.X = 0; // may have non-zero offset for multi-monitor setups
    ViewArea.Y = 0; // but we are only interested in offset relative to app view area

    switch (preferredPlacement)
    {
        case FlyoutPlacementMode.Right:
            if (desiredSize.Width < ViewArea.Width - placementTarget.Right) return FlyoutPlacementMode.Right;
            if (desiredSize.Width < placementTarget.Left) return FlyoutPlacementMode.Left;
            if (desiredSize.Height < placementTarget.Top) return FlyoutPlacementMode.Top;
            return FlyoutPlacementMode.Bottom;
        case FlyoutPlacementMode.Left:
            ...
    }
}
查看更多
登录 后发表回答