ContextMenu.PlacementTarget是没有得到设置,不知道为什么 [英] ContextMenu.PlacementTarget is not getting set, no idea why

查看:114
本文介绍了ContextMenu.PlacementTarget是没有得到设置,不知道为什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<DataTemplate x:Key="_ItemTemplateA">
  <Grid Tag="{Binding Path=DataContext.Command, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto"/>
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <ContentControl Content="{Binding}" ContentTemplate="{StaticResource ContentTemplateB}" Grid.Row="0" />
    <ContentControl Name="uiContentPresenter" Content="{Binding ContentView}" Grid.Row="1" Height="0" />
    <ContentControl DataContext="{Binding IsContentDisplayed}" DataContextChanged="IsDisplayed_Changed" Visibility="Collapsed" />
    <Grid.ContextMenu>
      <ContextMenu>
        <MenuItem Header="Text" 
              Command="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"
              CommandParameter="{Binding}" />
      </ContextMenu>
    </Grid.ContextMenu>
  </Grid>
</DataTemplate>

以上数据模板应用于一个ItemsControl。问题是,这是对网格指定的ContextMenu的PlacementTarget物业从未真正得到设为什么,所以我不能去这是必要的传递,应该在父用户控件执行按下Command网格的Tag属性上下文菜单。我利用这个方法断像这样类似的例子:<一href=\"http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/0244fbb0-fd5f-4a03-bd7b-978d7cbe1be3/\" rel=\"nofollow\">http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/0244fbb0-fd5f-4a03-bd7b-978d7cbe1be3/

The above data template is applied to an ItemsControl. The issue is that for the ContextMenu that is specified for the Grid, the PlacementTarget property is never actually getting set to anything so I cannot get to the Tag property of the Grid which is necessary for passing the Command that should execute on the parent UserControl down to the context menu. I've based this approach off of similar examples such as this: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/0244fbb0-fd5f-4a03-bd7b-978d7cbe1be3/

我已经无法识别通过这个命令下任何别的好办法。这是设置这种方式,因为我们使用的是MVV​​M的方法,使命令我们有这个模板被应用在用户控件的视图模型执行的生活。我已经试过明确设置PlacementTarget在几个不同的方式,但它仍然总是显示为未设置。

I've not been able to identify any other good way to pass this command down. This is setup this way because we are using an MVVM approach so the command we have to execute lives in the View Model of the user control this template is applied in. I've tried explicitly setting the PlacementTarget in a few different ways but it still always shows up as not set.

推荐答案

我知道这是旧的,并回答了,但它似乎不能正确回答。我碰到一个<少时href=\"http://stackoverflow.com/questions/6621550/how-to-get-the-placementtarget-on-wpf-context-menu-when-item-click-using-mvvm-pa/15306413#15306413\">similar发布并留下了一个完整的答案。你可能想看看,你可以得到它只是你的code一些调整工作。

I realise that this is old and answered, but it doesn't seem properly answered. I came across a similar post and left a full answer. You might like to take a look as you can get it working with just a few adjustments to your code.

首先,命名您的视图用户控件 ...我一般命名所有矿井为简单起见。然后记住,我们的视图模型绑定到的DataContext 用户控件,我们可以使用绑定到视图模型 {结合的DataContext,的ElementName =这}

First, name your view UserControl... I generally name all of mine This for simplicity. Then remembering that our view model is bound to the DataContext of the UserControl, we can bind to the view model using {Binding DataContext, ElementName=This}.

所以,现在我们可以绑定到视图模型,我们必须连接,与 ContextMenu.DataContext 。我用与对象的标签属性文本菜单(即 PlacementTarget )作为这方面,在这个例子中,电网

So now we can bind to the view model, we have to connect that with the ContextMenu.DataContext. I use the Tag property of the object with the ContextMenu (the PlacementTarget) as that connection, in this example, a 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 属性(在电网在我们的例子中):

We can then access the view model properties and commands in the ContextMenu by binding the ContextMenu.DataContext property to the PlacementTarget.Tag property (of the Grid in our example):

<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 电网在这种情况下,

Note the binding on the MenuItem.CommandTarget property. Setting this ensures that the target element on which the specified command is raised is the PlacementTarget, or the Grid in this case.

另外要注意的 CommandParameter 绑定。这绑定到的DataContext PlacementTarget 电网在这种情况下。在的DataContext 电网将从继承了的DataTemplate 所以你的数据产品现已绑定到对象参数在命令如果您正在使用的一些实施的ICommand 接口:

Also note the CommandParameter binding. This binds to the DataContext of the PlacementTarget, or the Grid in this case. The DataContext of the Grid will be inherited from the DataTemplate and so your data item is now bound to the object parameter in your Command if you're using some implementation of the ICommand interface:

public bool CanExecuteDeleteFileCommand(object parameter)
{
    return ((YourDataType)parameter).IsInvalid;
}

public void ExecuteDeleteFileCommand(object parameter)
{
    Delete((YourDataType)parameter);
}

或者,如果你正在使用某种形式的 RelayCommand 代表直接在您的视图模型:

Or if you are using some kind of RelayCommand delegates directly in your view model:

public ICommand Remove
{
    get 
    {
        return new ActionCommand(execute => Delete((YourDataType)execute), 
            canExecute => return ((YourDataType)canExecute).IsInvalid); 
    }
}

这篇关于ContextMenu.PlacementTarget是没有得到设置,不知道为什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆