Search code examples
wpfvb.netdata-bindingmenuitemicommand

How to Bind ICommand to a runtime built MenuItem


I have a collection of MenuItemViewModel, that is bound to a MenuItem's ItemsSource.

I would like to bind an ICommand to the MenuItem objects created through this binding.

The problem is that the actual MenuItem controls are only added at runtime, since I'm binding to their view models.

This is the GUI I have right now.

MenuItemViewModel.vb, containing the command to bind (all these members have corresponding public properties):

    Private _text As String
    Private _menuItems As IList(Of MenuItemViewModel)
    Private _commandMenuItem As RelayCommand

This is my NotifTilesViewModel:

Private _comPortMenuItems As ObservableCollection(Of MenuItemViewModel)
Public ReadOnly Property ComPortItems As ObservableCollection(Of MenuItemViewModel)
    Get
        Return _comPortMenuItems
    End Get
End Property

So, this ViewModel is the one I have bound to the notification tile UserControl you saw on the attached picture.

This is a relevant piece of my UserControl's XAML:

<Button.ContextMenu>
    <ContextMenu x:Name="notifTileContextMenu">
        <MenuItem Name="***" Command="{Binding Path=***}" Header="{Resx ResxName=***, Key=***}"/>
        <MenuItem Name="***" Header="{Resx ResxName=***, Key=***}"/>
        <Separator/>
        <MenuItem Name="mItemOpenPort" Header="{Resx ResxName=***, Key=***}" ItemsSource="{Binding Path=ComPortItems}"/>                                
    </ContextMenu>
</Button.ContextMenu>

As you can see, I bind the ItemsSource property to the ObservableCollection of MenuItemsViewModel.

But how can I also bind each of the correspondig MenuItem controls to the public property that I have for _commandMenuItem?


Solution

  • I don't have a Visual Studio available, but I think you can make do by using a style in the MenuItem with a bound ItemsSource.

    Something like this (probably not 100% correct, but it should give you the idea):

    <Button.ContextMenu>
        <ContextMenu x:Name="notifTileContextMenu">
            <MenuItem Name="***" Command="{Binding Path=***}" Header="{Resx ResxName=***, Key=***}"/>
            <MenuItem Name="***" Header="{Resx ResxName=***, Key=***}"/>
            <Separator/>
            <MenuItem Name="mItemOpenPort" Header="{Resx ResxName=***, Key=***}" ItemsSource="{Binding Path=ComPortItems}">
                <MenuItem.ItemContainerStyle>
                    <Style TargetType="MenuItem">
                        <Setter Property="Command" Value="{Binding FileOpenCommand}" />
                    </Style>
                </MenuItem.ItemContainerStyle>
            </MenuItem>
        </ContextMenu>
    </Button.ContextMenu>