When setting up the context menu using the style installer, the PlacementTarget property is null

In my application, I have a view (ListView) and a view model. Inside the view model, I have 2 properties: first a list of elements, and the second a command. I want to display elements (from the first property) inside a ListView. In addition, I want to have a context menu for each, where when you click on it, a command is activated (from the second property).

Here is the code for my view model:

public class ViewModel { public IEnumerable Items { get { return ...; //returns a collection of items } } public ICommand MyCommand //this is a command, I want to be able execute from context menu of each item { get { return new DelegateCommand(new Action<object>(delegate(object parameter) { //here code of the execution } ), new Predicate<object>(delegate(object parameter) { //here code of "can execute" })); } } 

Now part of XAML:

 <ListView ItemsSource="{Binding Items}"> <ListView.Resources> <commanding:CommandReference x:Key="myCommand" Command="{Binding MyCommand}"/> </ListView.Resources> <ListView.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Name}" /> </DataTemplate> </ListView.ItemTemplate> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Setter Property="ContextMenu"> <Setter.Value> <ContextMenu> <MenuItem Header="Remove from workspace" Command="{StaticResource myCommand}" CommandParameter="HERE I WANT TO PASS THE DATA CONTEXT OF THE ListViewItem" /> </ContextMenu> </Setter.Value> </Setter> </Style> </ListView.ItemContainerStyle> </ListView> 

Problem: Until I actually open the context menu, the PlacementTarget of the context menu is null. I need to somehow get the context data of the ListViewItem click in the "CanExecute" command, before calling the command - and I really want to do everything in XAML without handling callbacks in the code.

Thanks in advance.

+4
source share
1 answer

If you are looking for a ListViewItem DataContext , you can do this:

CommandParameter="{Binding}"

Change Here is what I tried:

 public partial class MainWindow : Window { private ObservableCollection<Person> list = new ObservableCollection<Person>(); public MainWindow() { InitializeComponent(); list.Add(new Person() { Name = "Test 1"}); list.Add(new Person() { Name = "Test 2"}); list.Add(new Person() { Name = "Test £"}); list.Add(new Person() { Name = "Test 4"}); this.DataContext = this; } public static ICommand MyCommand //this is a command, I want to be able execute from context menu of each item { get { return new DelegateCommand<Person>( a => Console.WriteLine(a.Name), a => true); } } public ObservableCollection<Person> Items { get { return this.list; } } } public class Person { public string Name { get; set; } } 

And xaml:

 <Window x:Class="ListView1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ListView1="clr-namespace:ListView1" Title="MainWindow" Height="350" Width="525"> <Grid> <ListView ItemsSource="{Binding Items}"> <ListView.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Name}" /> </DataTemplate> </ListView.ItemTemplate> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Setter Property="ContextMenu"> <Setter.Value> <ContextMenu> <MenuItem Header="Remove from workspace" Command="{x:Static ListView1:MainWindow.MyCommand}" CommandParameter="{Binding}" /> </ContextMenu> </Setter.Value> </Setter> </Style> </ListView.ItemContainerStyle> </ListView> </Grid> </Window> 
+1
source

All Articles