Я понимаю, что это старо и ответили, но, похоже, не ответили должным образом.Я наткнулся на аналогичный пост и оставил полный ответ.Возможно, вам захочется взглянуть на него, поскольку вы можете заставить его работать с помощью всего лишь нескольких настроек вашего кода.
Во-первых, назовите ваше мнение 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);
}
}