Skip to content

Conversation

gadfly3173
Copy link
Contributor

Sometimes the context menu may be set to null before opening. For example, the Avalonia repository has many branches. If you right-click multiple times before the context menu of the branch is opened, NRE will appear.

@love-linger
Copy link
Collaborator

In fact, ContextMenuExtension.OpenContextMenu is being called in UI thread, see:

image
image

and the code of ContextMenu.Open is

        private void Open(Control control, Control placementTarget, PlacementMode placement)
        {
            if (IsOpen)
            {
                return;
            }

            if (_popup == null)
            {
                _popup = new Popup
                {
                    IsLightDismissEnabled = true,
                    OverlayDismissEventPassThrough = true,
                };

                _popup.Opened += PopupOpened;
                _popup.Closed += PopupClosed;
                _popup.Closing += PopupClosing;
                _popup.KeyUp += PopupKeyUp;
            }

            _popup.SetPopupParent(control);

            _popup.Placement = placement;

            //Position of the line below is really important. 
            //All styles are being applied only when control has logical parent.
            //Line below will add ContextMenu as child to the Popup and this will trigger styles and they would be applied.
            //If you will move line below somewhere else it may cause that ContextMenu will behave differently from what you are expecting.
            _popup.Child = this;
            _popup.PlacementTarget = placementTarget;
            _popup.HorizontalOffset = HorizontalOffset;
            _popup.VerticalOffset = VerticalOffset;
            _popup.PlacementAnchor = PlacementAnchor;
            _popup.PlacementConstraintAdjustment = PlacementConstraintAdjustment;
            _popup.PlacementGravity = PlacementGravity;
            _popup.PlacementRect = PlacementRect;
            _popup.CustomPopupPlacementCallback = CustomPopupPlacementCallback;
            _popup.WindowManagerAddShadowHint = WindowManagerAddShadowHint;
            IsOpen = true;
            _popup.IsOpen = true;

            RaiseEvent(new RoutedEventArgs
            {
                RoutedEvent = OpenedEvent,
                Source = this,
            });
        }

I think the problem may caused by these code of SourceGit

private static void OnContextMenuClosing(object sender, CancelEventArgs e)
{
    if (sender is ContextMenu menu && menu.PlacementTarget != null)
        menu.PlacementTarget.ContextMenu = null;
}

@love-linger love-linger self-assigned this Sep 29, 2024
@love-linger love-linger added the bug Something isn't working label Sep 29, 2024
@love-linger
Copy link
Collaborator

BTW, this code is introduce by 0dea7ed with issue #140

@gadfly3173
Copy link
Contributor Author

Maybe just with control.ContextMenu?.Open(); is fine, or someone has a better solution?

@love-linger
Copy link
Collaborator

Maybe just with control.ContextMenu?.Open(); is fine, or someone has a better solution?

I can not reproduce this issue, but I think you are right.

@love-linger love-linger merged commit c7332af into sourcegit-scm:develop Sep 29, 2024
13 checks passed
@gadfly3173 gadfly3173 deleted the fix/context-menu-nre branch September 29, 2024 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants