Я понимаю, что это старый пост, но кто-то может найти это полезным знать.Предполагая, что вы связали свой вид с моделью представления, вы можете затем связать свой ContextMenu.DataContext
с моделью представления следующим образом:
Во-первых, назовите свое представление UserControl
... Я обычно называювсе мое This
для простоты.Затем, помня, что наша модель представления привязана к DataContext
из UserControl
, мы можем привязаться к модели представления, используя {Binding DataContext, ElementName=This}
.
Так что теперь мы можем привязаться к модели представления, мы должнысоедините это с ContextMenu.DataContext
.Я использую свойство Tag
объекта с ContextMenu
(PlacementTarget
) в качестве этого соединения, в этом примере Grid
:
<DataTemplate x:Key="YourTemplate" DataType="{x:Type DataTypes:YourDataType}">
<Grid ContextMenu="{StaticResource Menu}" Tag="{Binding DataContext,
ElementName=This}">
...
</Grid>
</DataTemplate>
Затем мы можем получить доступ к модели представлениясвойства и команды в ContextMenu
путем привязки свойства ContextMenu.DataContext
к свойству PlacementTarget.Tag
(в нашем примере Grid
):
<ContextMenu x:Key="Menu" DataContext="{Binding PlacementTarget.Tag, RelativeSource=
{RelativeSource Self}}">
<MenuItem Header="Delete" Command="{Binding DeleteFile}" CommandParameter=
"{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource
AncestorType=ContextMenu}}" CommandTarget="{Binding PlacementTarget,
RelativeSource={RelativeSource Self}}" />
</ContextMenu>
Обратите внимание на привязку к свойству MenuItem.CommandTarget
,Установка этого параметра гарантирует, что целевой элемент, для которого вызвана указанная команда, равен PlacementTarget
или Grid
в этом случае.
Также обратите внимание на привязку CommandParameter
.Это связывается с DataContext
из PlacementTarget
или Grid
в этом случае.DataContext
Grid
будет унаследовано от DataTemplate
, поэтому ваш элемент данных теперь привязан к параметру object
в вашем Command
, если вы используете какую-то реализацию интерфейса ICommand
:
public bool CanExecuteDeleteFileCommand(object parameter)
{
return ((YourDataType)parameter).IsInvalid;
}
public void ExecuteDeleteFileCommand(object parameter)
{
Delete((YourDataType)parameter);
}
Или, если вы используете какие-то RelayCommand
делегаты непосредственно в вашей модели представления:
public ICommand Remove
{
get
{
return new ActionCommand(execute => Delete((YourDataType)execute),
canExecute => return ((YourDataType)canExecute).IsInvalid);
}
}