WPF ContextMenu = {x:Null}但仍在ContentControl中显示菜单

7 c# wpf contextmenu contentcontrol

我需要禁用TextBox的标准ContextMenu.我创建了一个新的WPF项目并添加了以下内容:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
       <ContentControl>
           <ContentControl.ContentTemplate>
               <DataTemplate>
                    <TextBox ContextMenu="{x:Null}" VerticalAlignment="Top" HorizontalAlignment="Left" Width="50"></TextBox>
                </DataTemplate>
           </ContentControl.ContentTemplate>
       </ContentControl>
    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

但这就是我得到的:

在此输入图像描述

以下代码工作正常:

<Grid>
     <TextBox ContextMenu="{x:Null}" VerticalAlignment="Top" HorizontalAlignment="Left" Width="50"></TextBox>
</Grid>
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

更新.

根据接受的答案,我创建了一个派生自TextBox的类,以便能够显示父母ContextMenu.

    public class TextBoxNoMenu: TextBox
    {
        public TextBoxNoMenu()
        {
            ContextMenu = null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

Mik*_*bel 3

为什么会发生这种情况?

这是一个有趣的例子,控件的行为根据属性的设置位置/方式而变化。

TextBox默认情况下提供自己的上下文菜单。唯一不会执行此操作的情况是当您显式设置to的本地时。这就是您的简单示例中发生的情况,其中直接位于.ContextMenunullTextBoxGrid

但是,当您在 template 内设置属性时,您实际上并不是在设置本地值;而是在设置本地值。您正在设置“父模板”值。如果您使用 检查值DependencyPropertyHelper.GetValueSource(),您将看到基值源是ParentTemplate而不是Local。因此,菜单仍然会被覆盖。

有关不同类型的依赖属性值源的更多信息,请参阅依赖属性值优先级。

@OmegaMan 关于分配“隐藏”上下文菜单的建议似乎效果很好。