C# MVVM: MenuItem Command don´t execute in ViewModel - c#

I created a Delete MenuItem and binding a command to it.
Now I have the problem, if I am pressing the Delete MenuItem, nothing happens. Also if the program is executed with the debugger, it never reaches the private void DeleteItem.
xaml:
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="#F5F5F5" Width="80" Height="60" Margin="0,5,5,5">
<Border.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete"
Command="{Binding Path=DeleteItemCommand, RelativeSource={RelativeSource FindAncestor, AncestorType= MenuItem}}">
<MenuItem.Icon>
<Label FontFamily="#FontAwesome" Content="" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Border.ContextMenu>
ViewModel:
public ICommand DeleteItemCommand { get; set; }
DeleteItemCommand = new RelayCommand(DeleteItem);
private void DeleteItem(object obj)
{
try
{
// Do Magic
}
catch (Exception)
{
MessageBox.Show(error);
}
}
Would be great, if someone could help me or have any ideas how to solve it, because i can´t find the error.

ContextMenu is indeed not part of the visual tree. But I think because of that reason RelativeSource will not work because the binding will look up to the visual tree for the datacontext. contextMenu is not part of that visual tree so it will not find the proper datacontext. I've found a solution for this in the past using a proxy element in the resources for the window. Then set this proxyelement as content for a hidden contentcontrol in the window. On the menuItem set the CommandBinding to Datacontext.DeleteCommand and the soure to the static resource proxyelement. It is a bit hackish, but it works.
So to show some xaml, try this:
First in the resources of the window create a frameworkelement with the datacontext set to the windows datacontext (the viewmodel)
<Window.Resources>
<FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>
</Window.Resources>
Then use the resource for the content of a collapsed content control. And set the proper binding to the menuItem. Something like this:
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"/>
<ListBox x:Name="lbTest" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="#F5F5F5" Width="80" Height="60" Margin="0,5,5,5">
<Border.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete"
Command="{Binding DataContext.DeleteCommand, Source={StaticResource ProxyElement}}">
<MenuItem.Icon>
<Label FontFamily="#FontAwesome" Content="" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Border.ContextMenu>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
This should work. Give it a try.

Not sure if this will help but try using Binding instead of Binding Path.

ContextMenu is not part of VisualTree, that's why the binding fails. You can use some kind of relay like ContextMenu.PlacementTarget.Tag.Property as a cache for the second trail of binding search.
<ContextMenu>
<MenuItem Command="my:ImgTreeView.Folders" Header="Folders"
IsEnabled="{Binding Path=PlacementTarget.Tag.IsCheckFolder, RelativeSource={RelativeSource AncestorType=ContextMenu}}">
<MenuItem.Icon>
<Image Source="StarFolders.png" />
</MenuItem.Icon>
</MenuItem>
<!-- ... -->
</ContextMenu>

Related

A command from a context menu that does not work

Well, I have a WPF project and I'm using Visual Studio 2010. I'm using C# and XAML, and I'm using the MVVM pattern.
The problem I have must be simple but I just can't see why it's not working.
Alright, so I have a project with a ListBox. In that ListBox are many ChatNodes; each represented visually. The visual element for a ChatNode is here:
<ControlTemplate x:Key="NodeVisualTemplate">
<Grid>
<Border BorderThickness="2" Margin="2" CornerRadius="5,5,5,5" BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.SelectionMode, Converter={StaticResource SelectionModeToColourConverter}}" ContextMenu="{StaticResource ChatNodeMenu}">
<StackPanel Opacity="{Binding IsInvisibleNode, Converter={StaticResource ResourceKey=VisibleToOpacityConverter}}">
<TextBlock Text="Test" Background="AntiqueWhite"/>
<TextBlock Text="{Binding Path=NodeText}" Background="Aqua"/>
<StackPanel Orientation="Horizontal">
<TextBox Text="Type here" MinWidth="50"/>
<Image Source="{StaticResource ImgFolder}" Margin="0,0,5,0" Width="32" Height="32"/>
</StackPanel>
</StackPanel>
</Border>
</Grid>
</ControlTemplate>
I draw your attention to the BorderBrush for the Border. I will show that again here:
BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.SelectionMode, Converter={StaticResource SelectionModeToColourConverter}}"
This code sits inside a ListBoxItem and is able to find the parent ListBox and then access a property of it. This works fine. The property is in a view model called ChatNodeListViewModel and looks like this:
private int _selectionMode = 0;
public int SelectionMode
{
get { return _selectionMode; }
set
{
if (_selectionMode != value)
{
_selectionMode = value;
RaisePropertyChanged("SelectionMode");
}
}
}
I mention it specifically because another thing which is almost identical is not working, even though this BorderBrush code is working.
So, on to the not working part.
In that same ControlTemplate above, we see a ContextMenu, called 'ChatNodeMenu'. This is as follows:
<ContextMenu x:Key="ChatNodeMenu" >
<MenuItem Header="Remove" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.RemoveChatNodeCommand}" />
</ContextMenu>
It has the same binding, only this time it is for a Command called 'RemoveChatNodeCommand'. The menu does appear on a right click on a ChatNode, but the command does not run. I have actually used almost identical code in other parts of my project so I assume it's correct... but clearly there is an error somewhere.
So where is this command? It is in the view model called 'ChatNodeListViewModel' and I will present it here:
void RemoveChatNodeExecute()
{
MessageBox.Show("Remove chat node");
return;
}
bool CanRemoveChatNode()
{
return true;
}
public ICommand RemoveChatNodeCommand { get { return new RelayCommand(RemoveChatNodeExecute, CanRemoveChatNode); } }
I have also used this in many places throughout my code and it's worked every time but this one.
So, either there's a fault in the code or perhaps a simple mistake. I've checked the name of the command and re-copied it several times. I've checked the other parts of my code where I've used the same code, but I can't see anything wrong. I've cleaned and rebuilt my project just in case.
If anyone can venture a guess, I would be very happy with that.
The ListBox is not a visual ancestor of a ContextMenu but you could set the Tag property of the Border to the ListBox and then bind to the PlacementTarget of the ContextMenu:
<Border ... Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}" ContextMenu="{StaticResource ChatNodeMenu}">
<MenuItem Header="Remove" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Tag.DataContext.RemoveChatNodeCommand}" />
I have same issue related to conextmenu not able to work on command. could you help me to find solution.
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="test2">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="rr2" Command="{Binding DataContext.NextCommand, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}" CommandParameter="{Binding}" ></MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>

WPF Databinding ContextMenu of Button inside a DataTemplate inside an ItemsControl

I am trying to figure out how I can bind the ContextMenu of the Button that is being added in the ItemsControl I have. Basically, I'm wanting to be able to right click on a button and remove it from the observable collection that sits on my viewmodel. I understand that ContextMenu's are not part of the VisualTree, so using RelativeSource to walk up the tree to find my DataContext hasn't been useful to me.
The end goal of what I want to do is Bind the Command on the MenuItem to the RemoveCommand on my ViewModel and then pass in the Content property of the Button that you right click on so that I can remove it from the observable collection.
Any help on this would be greatly appreciated.
Model:
public class Preset
{
public string Name { get; set; }
}
ViewModel:
public class SettingsWindowViewModel
{
public ObservableCollection<Preset> MyPresets { get; } = new ObservableCollection<Preset>();
private ICommand _plusCommand;
public ICommand PlusCommand => _plusCommand ?? (_plusCommand = new DelegateCommand(AddPreset));
private ICommand _removeCommand;
public ICommand RemoveCommand => _removeCommand ?? (_removeCommand = new DelegateCommand<string>(RemovePreset));
private void AddPreset()
{
var count = MyPresets.Count;
MyPresets.Add(new Preset {Name = $"Preset{count+1}"});
}
private void RemovePreset(string name)
{
var preset = MyPresets.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.CurrentCultureIgnoreCase));
if (preset!= null)
{
MyPresets.Remove(preset);
}
}
}
XAML:
<Window x:Class="WpfTesting.Esper.Views.SettingsWindow"
x:Name="MainSettingsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:WpfTesting.Esper.ViewModels"
mc:Ignorable="d"
Title="SettingsWindow" Height="470" Width="612">
<Window.DataContext>
<viewModels:SettingsWindowViewModel/>
</Window.DataContext>
<Window.Resources>
<Style BasedOn="{StaticResource {x:Type MenuItem}}" TargetType="{x:Type MenuItem}" x:Key="PopupMenuItem">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border>
<ContentPresenter ContentSource="Header"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<Button Width="70" Content="Load"/>
<Button Width="70" Content="Save As"/>
<ItemsControl ItemsSource="{Binding MyPresets}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="70" Content="{Binding Name}">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Style="{StaticResource PopupMenuItem}" Header="Remove">
<!--
I need to set up binding a Command to a method on the DataContext of the Window, and I need to pass in the Content of the Button that is the parent of the ContextMenu
-->
</MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Width="20" Background="Transparent" BorderBrush="Transparent" Content="+" FontSize="21.333" HorizontalAlignment="Center" VerticalAlignment="Center" Command="{Binding PlusCommand}"/>
</StackPanel>
</Grid>
</Window>
Using WPF: Binding a ContextMenu to an MVVM Command as an introduction to what Tags can do, I figured out how to do what I was looking for by using multiple Tags to save the Context of what I was looking for.
I first made sure to give my window a x:Name
<Window x:Name="MainSettingsWindow"
Next, on the Button inside my DataTemplate of my ItemsControl, I set a Tag and set it to my Window
<ItemsControl ItemsSource="{Binding MyPresets}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="70" Content="{Binding Name}" Tag="{Binding ElementName=MainSettingsWindow}">
Next, in the ContextMenu, I seth the DataContext of the ContextMenu to the Tag I set on the Button, I also needed to create a Tag on the ContextMenu and point it back to the Content Property of the Button so that I can pass that into the CommandParameter
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=Self}}" Tag="{Binding PlacementTarget.Content, RelativeSource={RelativeSource Mode=Self}}">
At this point, I can now bind my MenuItem correctly using the Command from my ViewModel and the Content Property from the Button
This is the final XAML for my ItemsControl:
<ItemsControl ItemsSource="{Binding MyPresets}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="70" Content="{Binding Name}" Tag="{Binding ElementName=MainSettingsWindow}">
<Button.ContextMenu>
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=Self}}" Tag="{Binding PlacementTarget.Content, RelativeSource={RelativeSource Mode=Self}}">
<MenuItem Header="Remove"
Style="{StaticResource PopupMenuItem}"
Command="{Binding Path=DataContext.RemoveCommand}"
CommandParameter="{Binding Path=Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
One thing to note is that I had to change the CommandParameter on my ViewModel to take an Object instead of a String. The reason I did this was because I was getting an exception on the CanExecute method in my DelegateCommand
This is the exception I was getting:
Unable to cast object of type 'MS.Internal.NamedObject' to type 'System.String'.
I'm not sure exactly what's causing that exception to throw, but changing it to Object works ok for me.
I had basically a similar problem, and the solution I found was to use the Messenger class some MVVM frameworks like Devexpress or Mvvm Light have.
Basically you can register in a viewModel to listen for incoming messages. The class itself, at least in the Devexpress implementation works with weak references, so you may not even unregister message handlers and it will not cause memory leaks.
I had used this method for removing on right click tabs from a ObservableCollection, so it was similar to your scenario.
You can have a look here :
https://community.devexpress.com/blogs/wpf/archive/2013/12/13/devexpress-mvvm-framework-interaction-of-viewmodels-messenger.aspx
and here :
https://msdn.microsoft.com/en-us/magazine/jj694937.aspx

Getting ContextMenu target from Item in ItemsControl

I have an ItemsControl bound to a collection on my ViewModel. This ItemsControl presents several "Messages". I need a ContextMenu that, when clicked, provides an option to Copy that particular message to the clipboard.
The Command should activate on the ViewModel and the CommandParameter I want to pass is the Message itself.
The problem I'm having is getting the actual message that the ContextMenu has been opened OVER.
I've tried mutliple different approaches, but I cannot seem to figure out a way to pass the message as the Command's parameter.
Should I look for a different approach to accomplish this? Is the issue using an ItemsControl with an ItemsPresenter?
<ScrollViewer CanContentScroll="False"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
Grid.RowSpan="1">
<ItemsControl ItemsSource="{Binding MyActiveConversation.OrderedMessages, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding MyActiveConversation.IsOptOut, Converter={StaticResource BoolToEnabledInverter}}"
ItemTemplateSelector="{StaticResource tSelector}"
VirtualizingPanel.IsVirtualizing="False"
SourceUpdated="SourceUpdatedHandler" MinWidth="450">
<ItemsControl.ContextMenu>
<ContextMenu>
<MenuItem Header="Copy" Template="{DynamicResource MenuItemControlTemplate}"
CommandParameter="{Binding}" Command="{Binding Path=Data.CopyTextMessageCommand, Source={StaticResource ContextProxy}}">
</MenuItem>
</ContextMenu>
</ItemsControl.ContextMenu>
<ItemsControl.Template>
<ControlTemplate>
<Grid>
<ItemsPresenter VirtualizingPanel.IsVirtualizing="False"/>
</Grid>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
CommandParameter="{Binding}" works good for me, same for CommandParameter="{Binding .}"

Menu Item Binding WPF Issue

I have a problem with Menu Item Command Binding. I have used MVVM pattern
When I use right click, the menu appears. But when I click on the menu item doesn't work. Do you know why? Thanks
Here is the XAML:
<UserControl x:Class="PlotView.ViewModel.PlotViewControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:oxy="http://oxyplot.org/wpf"
mc:Ignorable="d"
xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
d:DesignHeight="400" d:DesignWidth="600"
x:Name="theViewName">
<UserControl.Resources>
</UserControl.Resources>
<GroupBox Name="GB" Header="Graphs" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderThickness="0">
<ListView Name="PlotLista" SelectedIndex="{Binding SelectedValue}" ItemsSource="{Binding PlotModelList}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<ListView.ItemTemplate>
<DataTemplate>
<oxy:Plot MinHeight="260" Height="Auto" IsRendering="True" FontStyle="Normal" FontFamily="Arial" FontSize="8" VerticalContentAlignment="Top" HorizontalContentAlignment="Left" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=ActualWidth}" Model="{Binding }">
<oxy:Plot.ContextMenu>
<ContextMenu>
<MenuItem Header="Export to PNG" Command="{Binding DataContext.SavePNG, ElementName=theViewName}"/>
</ContextMenu>
</oxy:Plot.ContextMenu>
</oxy:Plot>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</GroupBox>
</UserControl>
Here are a small portion of ViewModel:
#region Fields
private readonly DelegateCommand _menuClick=new DelegateCommand(this.MenuItemClick);
#endregion
#region Command
public ICommand SavePNG
{
get { return this._menuClick; }
}
#endregion
private void MenuItemClick()
{
// some code here
}
Error:
System.Windows.Data Error: 40 : BindingExpression path error:
'SavePNG' property not found on 'object' ''PlotModel'
(HashCode=15385318)'. BindingExpression:Path=SavePNG;
DataItem='PlotModel' (HashCode=15385318); target element is 'MenuItem'
(Name=''); target property is 'Command' (type 'ICommand')
Your binding is trying to find SavePNG on your Item, not your ViewModel.
Instead, give your view an x:Name, or a Name, and use the following binding instead:
{Binding DataContext.SavePNG, ElementName=theViewName}
Assuming that SaveCommand is on the same ViewModel which contains your collection.
ContextMenus are a little different in wpf as they are not part of the visual tree of the control. As such they cannot 'see' any elements by relative source or by elementnames.
A little cheat is to use the PlacementTarget property and get the datacontext with that. Change your ListView to below to make it work. Notice the tag property on the ListView and the DataContext property on the ContextMenu.
<ListView Name="PlotLista" SelectedIndex="{Binding SelectedValue}" ItemsSource="{Binding PlotModelList}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Tag="{Binding DataContext,ElementName=theViewName}">
<ListView.ItemTemplate>
<DataTemplate>
<oxy:Plot MinHeight="260" Height="Auto" IsRendering="True" FontStyle="Normal" FontFamily="Arial" FontSize="8" VerticalContentAlignment="Top" HorizontalContentAlignment="Left" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=ActualWidth}" Model="{Binding }">
<oxy:Plot.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Export to PNG" Command="{Binding SavePNG}"/>
</ContextMenu>
</oxy:Plot.ContextMenu>
</oxy:Plot>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This wasn't written in visual studio so please check the syntax:
<ListView Tag="{Binding Path=DataContext,ElementName=theViewName}">
<ListView.ItemTemplate>
<DataTemplate>
<oxy:Plot Tag="{Binding Path=Tag,RelativeSource={RelativeSource AncestorType=ListView}">
<oxy:Plot.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Command="{Binding SavePNG}"/>
</ContextMenu>
</oxy:Plot.ContextMenu>
</oxy:Plot>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

WPF Caliburn.Micro ItemsControl ContextMenu don't find method

I'am really having some problems with the ContextMenu from Caliburn.Micro. No matter what I do, I get the error "Cant' find the method ...".
I've tried this solutions, and that one too, but I can't get this to work.
What I'am doing wrong? Actually, there's a way to debug the view and find out in which Context the control is searching for the respective ViewModel?
And another thing... this View is inside a DataTemplate from another view, does that change anything? All the others bindings are working from the correct ViewModel...
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
Grid.Row="1" Grid.Column="0"
Padding="10,5,15,5"
MaxHeight="390" x:Name="xImages">
<ItemsControl
ItemsSource="{Binding Path=Document.Images}"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Height="110">
<Border Margin="5" BorderBrush="Gainsboro" BorderThickness="1">
<Image Source="{Binding Path=PathThumb}" Width="70" Height="100"> <!-- Tag="{Binding DataContext, ElementName=xImagens}" -->
<Image.ContextMenu>
<ContextMenu
cal:Action.TargetWithoutContext="{Binding DataContext, ElementName=xImagens}"> <!--PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"-->
<MenuItem Header="Ampliar"
cal:Message.Attach="[Event Click] = [Action ExpandImage($datacontext)]"></MenuItem>
<MenuItem Header="Excluir"
cal:Message.Attach="[Event Click] = [Action DeleteImage($datacontext)]"></MenuItem>
</ContextMenu>
</Image.ContextMenu>
</Image>
</Border>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
cal:Action.TargetWithoutContext="{Binding Source={x:Reference xImagens} , Path=DataContext}">
Because ContextMenu is not part of the VisualTree , you can't bind to elements in the visual tree
of it's TargetPlacement. ( Though in XAML it seems like it is part of it ).
You have two choices:
{Binding Path=PlacementTarget.DataContext}
Or:
{Binding Source={x:Reference xImagens}, Path=DataContext}
give the x:Name="xImages" to the ItemsControl and then do the binding with ElementName to the ContextMenu using the Action.TargetWithoutContext, you had it right but the ScrollViewer isn't what has the Datacontext to the List of data, the ItemControl does since it has the ItemSource.
Was there a reason for naming the ScrollViewer?
<ItemsControl x:Name="xImages">
<ContextMenu Action.TargetWithoutContext="{Binding Path=DataContext, ElementName=xImages}">
<!-- Shortened -->
</ContextMenu>
</ItemsControl>

Categories