wpfcontextmenudotnetbar

Problem adding a nested MenuItem - nested items not showing


I am trying to add nested (sub) menu items. The main menu items are showing but not the sub ones. Clearly I am missing a property, but can't figure it out. Any pointers will be greatly appreciated.

Also tried adding the sub menu items to a ContextMenu then adding that to the MenuItem ContextMenu property, but that doesn't work either.

Private Function ReturnContexMenu() As ContextMenu
Try
    Dim FlagMI As New MenuItem
    With FlagMI
        .Header = "Quick Flag"
        .Name = "FlagMI"
    End With
    RegisterControl(Inbox_Grid, FlagMI)

    Dim MarkReadMI As New MenuItem
    With MarkReadMI
        .Header = "Mark as read"
        .Name = "MarkReadMI"
    End With
    RegisterControl(Inbox_Grid, MarkReadMI)

    Dim MarkUnreadMI As New MenuItem
    With MarkUnreadMI
        .Header = "Mark as unread"
        .Name = "MarkUnreadMI"
    End With
    RegisterControl(Inbox_Grid, MarkUnreadMI)

    Dim MarkAsMI As New MenuItem
    With MarkAsMI
        .Header = "Mark as "
        .Items.Add(MarkReadMI)
        .Items.Add(MarkUnreadMI)
    End With

    Dim vMainContext As New ContextMenu
    With vMainContext
        .Name = "MainContextMenu"

        .Items.Add(FlagMI)
        .Items.Add(MarkAsMI)
    End With

    Return vMainContext
Catch ex As Exception
    EmailError(ex)
    Return Nothing
End Try
End Function  

==========UPDATED==================

As you can see from the screenshot the sub menu items are not showing! Also tried this with a button and the same result. Could this be an issue with.NET 8? - Nope! Same problem with .NET 4.8 using a button.

MenuItem


Solution

  • After figuring out that the issue disappears after removing the reference to a 3rd party control library, we can conclude that the library is changing the default layout by providing an implicit Style.
    This Style seems to remove the items host for the child items, which is the reason that the subitems of the MenuItem are not rendered anymore.

    Making use of the knowledge about the dependency property precedence list we know we can prevent any implicit Style from being applied by setting a local value e.g. null or Nothing. This way the MenuItem is forced to use its default Style.

    VB.NET

    Private Function ReturnContexMenu() As ContextMenu
        Try
            Dim FlagMI As MenuItem = New MenuItem() With {
                .Style = Nothing
            }
    
            If True Then
                Dim withBlock = FlagMI
                withBlock.Header = "Quick Flag"
                withBlock.Name = "FlagMI"
            End If
    
            RegisterControl(Inbox_Grid, FlagMI)
            Dim MarkReadMI As MenuItem = New MenuItem() With {
                .Style = Nothing
            }
    
            If True Then
                Dim withBlock = MarkReadMI
                withBlock.Header = "Mark as read"
                withBlock.Name = "MarkReadMI"
            End If
    
            RegisterControl(Inbox_Grid, MarkReadMI)
            Dim MarkUnreadMI As MenuItem = New MenuItem() With {
                .Style = Nothing
            }
    
            If True Then
                Dim withBlock = MarkUnreadMI
                withBlock.Header = "Mark as unread"
                withBlock.Name = "MarkUnreadMI"
            End If
    
            RegisterControl(Inbox_Grid, MarkUnreadMI)
            Dim MarkAsMI As MenuItem = New MenuItem() With {
                .Style = Nothing
            }
    
            If True Then
                Dim withBlock = MarkAsMI
                withBlock.Header = "Mark as "
                withBlock.Items.Add(MarkReadMI)
                withBlock.Items.Add(MarkUnreadMI)
            End If
    
            Dim vMainContext As ContextMenu = New ContextMenu()
    
            If True Then
                Dim withBlock = vMainContext
                withBlock.Name = "MainContextMenu"
                withBlock.Items.Add(FlagMI)
                withBlock.Items.Add(MarkAsMI)
            End If
    
            Return vMainContext
        Catch ex As Exception
            EmailError(ex)
            Return Nothing
        End Try
    End Function
    

    C#

    private ContextMenu ReturnContexMenu()
    {
        try
        {
            MenuItem FlagMI = new MenuItem() { Style = null };
            {
                var withBlock = FlagMI;
                withBlock.Header = "Quick Flag";
                withBlock.Name = "FlagMI";
            }
            RegisterControl(Inbox_Grid, FlagMI);
    
            MenuItem MarkReadMI = new MenuItem() { Style = null };
            {
                var withBlock = MarkReadMI;
                withBlock.Header = "Mark as read";
                withBlock.Name = "MarkReadMI";
            }
            RegisterControl(Inbox_Grid, MarkReadMI);
    
            MenuItem MarkUnreadMI = new MenuItem() { Style = null };
            {
                var withBlock = MarkUnreadMI;
                withBlock.Header = "Mark as unread";
                withBlock.Name = "MarkUnreadMI";
            }
            RegisterControl(Inbox_Grid, MarkUnreadMI);
    
            MenuItem MarkAsMI = new MenuItem() { Style = null };
            {
                var withBlock = MarkAsMI;
                withBlock.Header = "Mark as ";
                withBlock.Items.Add(MarkReadMI);
                withBlock.Items.Add(MarkUnreadMI);
            }
    
            ContextMenu vMainContext = new ContextMenu();
            {
                var withBlock = vMainContext;
                withBlock.Name = "MainContextMenu";
    
                withBlock.Items.Add(FlagMI);
                withBlock.Items.Add(MarkAsMI);
            }
    
            return vMainContext;
        }
        catch (Exception ex)
        {
            EmailError(ex);
            return null/* TODO Change to default(_) if this is not a reference type */;
        }
    }