1

I have a ContextMenu and a button, inside a TabControl, I got the button Command to work correctly, but couldn't figure out how to bind the Context menu items commands. Could you point out what I'm doing wrong?

Note: Both commands CloseTabCommandand CloseAllTabsCommand, are working fine when binding them to the button.

Xaml code:

<TabControl ItemsSource="{Binding TabItems}">
                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <DockPanel Width="120" ToolTip="{Binding HeaderText}">
                            <DockPanel.ContextMenu>
                                <ContextMenu>
                                    <MenuItem Header="Close Tab"
                                              Command="{Binding DataContext.CloseTabCommand, RelativeSource={RelativeSource AncestorType=TabControl}}"
                                              CommandParameter="{Binding ItemId}" />
                                    <MenuItem Header="Close All Tabs"
                                              Command="{Binding DataContext.CloseAllTabsCommand, RelativeSource={RelativeSource AncestorType=TabControl}}" />
                                </ContextMenu>
                            </DockPanel.ContextMenu>
                            <Button
                                Command="{Binding DataContext.CloseTabCommand, RelativeSource={RelativeSource AncestorType=TabControl}}"
                                CommandParameter="{Binding ItemId}"
                                Content="X"
                                Cursor="Hand"
                                DockPanel.Dock="Right"
                                Focusable="False"
                                FontFamily="Courier"
                                FontWeight="Bold"
                                FontSize="10"
                                VerticalContentAlignment="Center"
                                Width="15" Height="15" />
                            <ContentPresenter Content="{Binding HeaderText}" VerticalAlignment="Center" />
                        </DockPanel>
                    </DataTemplate>
                </TabControl.ItemTemplate>
                <TabControl.ItemContainerStyle>
                    <Style TargetType="TabItem">
                        <Setter Property="IsSelected" Value="{Binding IsSelected}" />
                    </Style>
                </TabControl.ItemContainerStyle>
            </TabControl>

ViewModel code:

private ObservableCollection<TabItemViewModel> _tabItems;
        public ObservableCollection<TabItemViewModel> TabItems {
            // if _tabItems is null initiate object.
            get { return _tabItems; }
            set { SetProperty(ref _tabItems, value); }
        }

Edit:

Binding to a Command declared in TabItemViewModel(TabControl ItemsSource) class works fine. but I want to bind commands to ViewModel for current UserControl

IBRA
  • 1,502
  • 3
  • 24
  • 56
  • 1
    Did you look at this? http://stackoverflow.com/questions/15033522/wpf-contextmenu-woes-how-do-i-set-the-datacontext-of-the-contextmenu – blins Jan 22 '17 at 14:38

2 Answers2

3

Bind the Tag property of the DockPanel to the view model and then bind the Command property of the MenuItem to the PlacementTarget of the ContextMenu:

<DockPanel Width="120" ToolTip="{Binding HeaderText}"
           Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=TabControl}}">
    <DockPanel.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Close Tab"
                      Command="{Binding PlacementTarget.Tag.CloseTabCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
                      CommandParameter="{Binding ItemId}" />
            ...

A ContextMenu resides in its own visual tree and this is why you can't use a RelativeSource to the bind to the parent TabControl as there is no parent TabControl further up in the visual tree.

mm8
  • 163,881
  • 10
  • 57
  • 88
0

Have you tried binding your AncestorType to Window or UserControl?

Command="{Binding CloseTabCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
Ali Baig
  • 3,819
  • 4
  • 34
  • 47
  • I tried with and without DataContext, on both commands, I've tried moving the ContextMenu inside the button code, just for testing. and it didn't work either. just to clarify on Button command they both worked, but when using it didn't work – IBRA Jan 22 '17 at 14:31
  • btw I can bind to TabControl sourceItem class, please check the update – IBRA Jan 22 '17 at 14:37