I have a TabControl
and have bound its ItemSource
to a ObserverableCollection
of view models. I have also set its DataTemplate
to the view assioated with the view model.
This works fine and in ItemContainerStyle
I added a ContextMenu
that have a MenuItem
. How do I get the MenuItems
click event to fire in my code? I am not able to pick up the event in Delete_OnClick
. Also the sender should be a reference to the view model that is bound to the ItemSource
of the TabControl
.
<TabControl ItemsSource="{Binding MyTabItems}">
<TabControl.Resources>
<DataTemplate DataType="{x:Type viewModels:MyTabItemViewModel}">
<views:MyTabItem/>
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Header" Value="{Binding Path=Header}"/>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Delete" Click="Delete_OnClick"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
// In code behind I have this method that should be triggered when the
// Delete MenuItem is clicked
private void Delete_OnClick(object sender, RoutedEventArgs e)
{
var tabItem = (ITabItem) sender;
ViewModel.DeleteTab(tabItem);
}
Summary: I can right click on the tab header and click on Delete but I do not get any events from that.
I changed my original answer considerably.
My understanding is that you use MVVM pattern. If so you shouldn't use event handlers directly. Instead you should bind a menu item to a command.
<ContextMenu>
<MenuItem Header="Delete" Command={Binding MyCommand} />
</ContextMenu>
MyCommand
should be a property defined in your MyTabItemViewModel
class.
public class MyTabItemViewModel
{
public ICommand MyCommand { get; set; }
...
}
MyCommand
property can return an instance of any class that implements ICommand interface. It can be a predefined command (for example see ApplicationCommands class) or your own. Here is an example how your DeleteCommand
could look like:
public class DeleteCommand: ICommand
{
private ParentVM Parent { get; set; }
private MyTabItemViewModel Item { get; set; }
public MyCustomCommand (ParentVM parent, MyTabItemViewModel item)
{
Parent= parent;
Item = item;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
parent.RemoveItem(item);
}
...
}
I assumed that your view model with the MyTabItems
collection is called ParentVM
and that it has a public method RemoveItem
which is responsible for removing a given item from this collection.
You can instantiate DeleteCommand
in the constructor of MyTabItemViewModel
. For example:
public class MyTabItemViewModel
{
public ICommand MyCommand { get; set; }
public MyTabItemViewModel(ParentVM parent)
{
MyCommand = new DeleteCommand(parent, this);
}
...
}
Use an EventSetter instead, that should work in your case
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Delete" >
<MenuItem.Style>
<Style TargetType="MenuItem">
<EventSetter Event="Click" Handler="Delete_OnClick"/>
</Style>
</MenuItem.Style>
</MenuItem>
</ContextMenu>
</Setter.Value>
</Setter>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.