I have three tabs and each has a listbox with different types of files.
When I right-click on an item in the listbox, I want a ContextMenu with "New, Edit and Delete" as Item headers.
I guess I could have a ContextMenu for each listbox, and then have a seperate method for each header, such as:
<ListBox.ContextMenu>
<ContextMenu x:Name="NewEditDeleteAdvCalcFileContextMenu">
<MenuItem Name="NewAdv" Header="New" Click="NewAdv_Click" />
<MenuItem Name="EditAdv" Header="Edit" Click="EditAdv_Click"/>
<MenuItem Name="DeleteAdv" Header="Delete" Click="DeleteAdv_Click"/>
</ContextMenu>
</ListBox.ContextMenu>
But really, I hope there is a better way.
I saw this post which shows the ContextMenu as Static Resource
and this seems to be something I would like to do. In the same thread it is suggested to use commands: ContextMenu with Commands
and with that I'm hoping I can get the type of the ListBoxItem that was clicked, because I need that. A new file type B must be handled differently than a new file type C, but I don't want a gazillion contextmenus and New/Edit/Delete methods.
So, currently I have this higher up in my xaml file:
<UserControl.Resources>
<ContextMenu x:Key="NewEditDeleteContextMenu">
<MenuItem Header="New"
Command="{Binding Path=NewFileCommand}"
CommandTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"/>
<MenuItem Header="Edit"
Command="{Binding Path=EditFileCommand}"
CommandTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"/>
<MenuItem Header="Delete"
Command="{Binding Path=DeleteFileCommand}"
CommandTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"/>
</ContextMenu>
</UserControl.Resources>
And then a listbox in the tabItem:
<ListBox Name="CalcFilesListBox"
Margin="20" ItemsSource="{Binding CalcFilesList}"
PreviewMouseRightButtonUp="ListBox_PreviewMouseRightButtonUp"
ContextMenu="{StaticResource NewEditDeleteContextMenu}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<EventSetter Event="MouseDoubleClick" Handler="CalcFileListBox_MouseDoubleClick"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Question #1
How do I get the rightclick of a ListBoxItem to show the ContextMenu, which is now a static resource? Because in my xaml.cs I had this:
private void ListBox_PreviewMouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
// SelectItemOnRightClick(e);
NewEditDeleteContextMenu.PlacementTarget = sender as UIElement;
NewEditDeleteContextMenu.IsOpen = true;
}
But now I have an error saying:
The name 'NewEditDeleteContextMenu' does not exist in the current context.
because originally I had the contextmenu as part of the ListBox such as:
<ListBox.ContextMenu>
...
But as far as I could see that would mean a separate ContextMenu for each ListBox.
Question #2
Is the correct way to use a command, let's say NewFileCommand for the New item header in the ContextMenu (shown in the UserControl.Resources block of code) to do the following:
In my ViewModel:
public RelayCommand<string> NewFileCommand { get; private set; }
and then in the ViewModel's constructor:
public CalcViewModel()
{
NewFileCommand = new RelayCommand<object>(NewFile);
}
public void NewFile(object sender)
{
//Determine the type of file, based on the ListBoxItem's DataContext.
That is, supposing the ListBoxItem is the object being passed as the sender.
}
Basically, I want one ContextMenu bound to the different ListBox components, and this should pop up on a rightclick, and when for instance the New item is chosen on the ContextMenu, I want to determine the type of the file that has been bound to the ListBox. E.g.: ListBox 1 is bound to a collection of file type B. ListBox 2 is bound to a collection of file type C. When I rightclick on an item in ListBox 2, and choose New, I need to make a new file of type C.
Question #3
This isn't a very intricate View. I haven't used a MVVM framework because so far I haven't thought that the time it would take me to learn one would be worth it, but considering this scenario, and a simpler case for a double-click on the ListBoxItems that can be seen in one of the blocks of code, would you recommend the use of a framework?