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

1

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

0

Have you tried binding your AncestorType to Window or UserControl?

Command="{Binding CloseTabCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" 

2 Comments

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 <Button.ContextMenu><MenuItem Command="CloseTabCommand" /> it didn't work
btw I can bind to TabControl sourceItem class, please check the update

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.