Reputation: 358
I have ListBox with ItemsSource binded to ObservableCollection in ViewModel and I need to show ContextMenu for each item in ListBox. ListBox looks like this:
<ListBox x:Name="DriversPanel" ItemsSource="{Binding Employees}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Command="{BINDING TO FUNCTION "ButtonAction" HERE}" Header="Some action"/>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.Styles>
<Style Selector="ListBoxItem">
<!--style settings-->
</Style>
</ListBox.Styles>
</ListBox>
here I am facing an error, when I write only Command="{Binding ButtonAction}" it looks for this function in Employee object. But this function is in the main ViewModel. Viwmodel is working because binding to Employees ObservableCollection works well. I tried these solutions:
<MenuItem Command="{Binding DataContext.ButtonAction, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}" Header="Some action"/>
and
<MenuItem Command="{Binding $parent[ListBox].DataContext.ButtonAction}" Header="Some action"/>
but none of them worked. The function is created in ViewModel which looks like this:
internal class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private ObservableCollection<Employee> _employes = new ObservableCollection<Employee>();
public ObservableCollection<Employee> Employees
{
get => _employes;
set
{
_employes = value;
OnPropertyChanged(nameof(Employees));
}
}
public void ButtonAction()
{
Console.WriteLine("It works!");
OnPropertyChanged(nameof(Employees));
}
}
Employee is just an ordinary object:
internal class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
Any ideas please?
Upvotes: 1
Views: 1340
Reputation: 358
So I found a solution. For binding to parent's ViewModel I need to use this:
<MenuItem Command="{Binding #DriversPanel((vm:MainViewModel)DataContext).ButtonAction}" Header="Some action"/>
Upvotes: 2