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