Getting Actual Placement of a Flyout

2019-08-27 04:06发布

问题:

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:

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?

回答1:

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:
            ...
    }
}


回答2:

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.