【问题标题】:How to get the PlacementTarget on WPF Context menu when item click using MVVM pattern使用 MVVM 模式单击项目时如何在 WPF 上下文菜单上获取 PlacementTarget
【发布时间】:2011-07-08 07:55:19
【问题描述】:

使用MVVM模式时如何获取选中的ContextMenu的PlacementTarget?

使用 MenuItem 点击事件时,我可以像这样获得 PlacementTarget。但它是如何做到的 MVVM 呢?

   public void changeGaugeColor(object sender, RoutedEventArgs e)
    {
        MenuItem tempMenuItem = (MenuItem)sender;

        MenuItem mi = (MenuItem)sender;
        bd = (BidirectionalDial)cm.PlacementTarget;

    }

【问题讨论】:

  • 您的展示位置目标难道不是同一个用户控件的一部分吗?您可以使用 this.yourControlName 直接访问它吗?您要做什么?
  • 问题必须编辑!你想要什么?
  • 如果您的 ViewModel 正在寻找放置目标,那么您做错了。这是 View 的所有权限,而不是 ViewModel。让视图在代码隐藏中完成所有这些工作。

标签: wpf mvvm contextmenu


【解决方案1】:

我知道这是一篇旧帖子,但有人可能会觉得这很有用。假设您已将视图绑定到您的视图模型,那么您可以通过以下方式将您的 ContextMenu.DataContext 绑定到您的视图模型:

首先,将您的视图命名为UserControl...为简单起见,我通常将我的所有视图命名为This。然后记住我们的视图模型是绑定到UserControlDataContext,我们可以使用{Binding DataContext, ElementName=This}绑定到视图模型。

所以现在我们可以绑定到视图模型,我们必须将它与ContextMenu.DataContext 连接起来。我使用对象的Tag 属性和ContextMenuPlacementTarget)作为连接,在本例中为Grid

<DataTemplate x:Key="YourTemplate" DataType="{x:Type DataTypes:YourDataType}">
    <Grid ContextMenu="{StaticResource Menu}" Tag="{Binding DataContext, 
        ElementName=This}">
        ...
    </Grid>
</DataTemplate>

然后我们可以通过将ContextMenu.DataContext 属性绑定到PlacementTarget.Tag 属性(在我们的示例中为Grid)来访问ContextMenu 中的视图模型属性和命令:

<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 绑定。这将绑定到PlacementTargetDataContext,或者在这种情况下绑定到GridGridDataContext 将从 DataTemplate 继承,因此如果您正在使用 ICommand 接口的某些实现,则您的数据项现在绑定到 Command 中的 object 参数:

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); 
    }
}

【讨论】:

    猜你喜欢
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 2017-05-13
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    相关资源
    最近更新 更多