WPF:如何设置或禁用 TextBox 的默认 ContextMenu

Posted

技术标签:

【中文标题】WPF:如何设置或禁用 TextBox 的默认 ContextMenu【英文标题】:WPF: How to style or disable the default ContextMenu of a TextBox 【发布时间】:2010-09-05 19:05:31 【问题描述】:

显然,当用户在我们的 WPF 应用程序中右键单击并使用 Windows 经典主题时,TextBox 的默认 ContextMenu(包含复制、剪切和粘贴)具有黑色背景。

我知道这很好用:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <TextBox ContextMenu="x:Null"/>

</Page>

但这不起作用:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Page.Resources>

 <Style x:Key="x:Type TextBox" TargetType="x:Type TextBox">
   <Setter Property="ContextMenu" Value="x:Null"/>
</Style>
</Page.Resources>

  <TextBox/>
</Page> 

有谁知道如何为 WPF 中的所有 TextBox 设置样式或禁用默认 ContextMenu?

【问题讨论】:

你不需要考虑禁用快捷键,例如CTRL-V? 【参考方案1】:

这是我一直使用的方式:

      <TextBox x:Name="MyTextbox">
         <TextBox.ContextMenu>
         <ContextMenu Visibility="Hidden"/>
         </TextBox.ContextMenu>
      </TextBox>

也可以使用:

           MyTextbox.ContextMenu.Visibility = Visibility.Hidden;
           MyTextbox.ContextMenu.Visibility = Visibility.Visble;

【讨论】:

不鼓励仅使用代码的答案。请单击编辑并添加一些单词来总结您的代码如何解决问题,或者解释您的答案与之前的答案/答案有何不同。谢谢 @Cœur 这真的很酷。我以前没见过,但将来肯定会使用它。有这样有用的功能的文档页面吗? 现在看看,在某些情况下更有用。【参考方案2】:

没关系,如果您不提供密钥,它将使用TargetType 作为密钥,就像我的示例使用的方式一样:)

取自 MSDN 关于 Style:

TargetType 属性设置为TextBlock 类型 设置 x:Key 会隐式地将 x:Key 设置为 x:Type TextBlock。这也意味着,如果您 > > 为上述样式提供 x:Key 值,而不是 x:Type TextBlock,则样式 不会自动应用于所有 TextBlock 元素。反而, 您需要将样式显式应用于TextBlock 元素。

http://msdn.microsoft.com/en-us/library/system.windows.style.targettype.aspx

【讨论】:

【参考方案3】:

奇怪。 ContextMenu="x:Null" 不能解决问题。

但确实如此:

<TextBox.ContextMenu>
    <ContextMenu Visibility="Collapsed">
    </ContextMenu>
</TextBox.ContextMenu>

【讨论】:

【参考方案4】:

由于一个较晚的错误报告,我们发现我们无法在部分受信任的应用程序中直接使用 ApplicationComands Cut Paste and Copy。因此,在您的控件的任何命令中使用这些命令在执行时绝对不会执行任何操作。

所以从本质上讲,布拉德斯的答案几乎就在那里,它看起来确实是正确的方式,即没有黑色背景,但没有解决问题。

我们决定根据 Brads 的回答“删除”菜单,如下所示:

<ContextMenu x:Key="TextBoxContextMenu" Width="0" Height="0" />

然后像这样使用这个空的上下文菜单:

<Style TargetType="x:Type TextBox">
  <Setter Property="ContextMenu" Value="StaticResource TextBoxContextMenu" />
</Style>

【讨论】:

或者你可以使用 ,它也可以。 此外,将 ContextMenu 上的 IsEnabled 设置为 false 可以避免在用户尝试右键单击时出现焦点“冻结”的问题。【参考方案5】:

要为所有文本框设置 ContextMenu 的样式,我会执行以下操作:

首先,在资源部分,添加一个 ContextMenu,您计划将其用作文本框中的标准 ContextMenu。 例如

<ContextMenu x:Key="TextBoxContextMenu" Background="White">
  <MenuItem Command="ApplicationCommands.Copy" />
  <MenuItem Command="ApplicationCommands.Cut" />
  <MenuItem Command="ApplicationCommands.Paste" />
</ContextMenu>

其次,为您的文本框创建一个样式,它使用上下文菜单资源:

<Style TargetType="x:Type TextBox">
  <Setter Property="ContextMenu" Value="StaticResource TextBoxContextMenu" />
</Style>

最后,正常使用你的文本框:

<TextBox />

如果您只想将此上下文菜单应用于某些文本框,请不要创建上面的样式,并将以下内容添加到您的 TextBox 标记中:

<TextBox ContextMenu="StaticResource TextBoxContextMenu" />

希望这会有所帮助!

【讨论】:

很抱歉偶然发现了一个错误。我从来没有意识到这一点,但我不能在部分信任下直接使用 ApplicationCommands 剪切、复制和粘贴。这个菜单在部分信任下无法工作。单击菜单项,绝对没有任何作用.. 很抱歉花了将近 18 个月的时间才发现 ;) 您的回答让我找到了我的新解决方案:使用空菜单禁用菜单.. 再次感谢您的回答!【参考方案6】:

尝试从 Style 资源中删除 x:Key 属性,保留 TargetType。我知道,您应该拥有 x:Key 作为资源,但如果您将它与 TargetType 一起拥有,则 Key 占上风。

这是我在一个项目中使用的示例样式,用于为我的一个应用程序中的所有工具提示设置外观(在 App.Resources 中--notice,no Key)

 <Style
    TargetType="x:Type ToolTip">
    <Setter
      Property="Template">
      <Setter.Value>
        <ControlTemplate
          TargetType="x:Type ToolTip">
          <Grid
            Width="TemplateBinding Width"
            Height="TemplateBinding Height">
            <Rectangle
              RadiusX="9"
              RadiusY="9"
              Stroke="LightGray"
              StrokeThickness="2">
              <Rectangle.Fill>
                <RadialGradientBrush>
                  <GradientStop />
                  <GradientStop
                    Color="FloralWhite"
                    Offset="0" />
                  <GradientStop
                    Color="Cornsilk"
                    Offset="2" />
                </RadialGradientBrush>
              </Rectangle.Fill>
            </Rectangle>
            <ContentPresenter
              Margin="6 4 6 4" />
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>

【讨论】:

以上是关于WPF:如何设置或禁用 TextBox 的默认 ContextMenu的主要内容,如果未能解决你的问题,请参考以下文章

WPF 禁用TextBox的触摸后自动弹出虚拟键盘

WPF 禁用TextBox的触摸后自动弹出虚拟键盘

将 ErrorTemplate 添加到 WPF 用户控件会禁用 TextBox 输入

根据WPF中的TextBox Text属性启用/禁用按钮?

如何禁用 WPF WebBrowser 控件的点击噪音?

WPF TextBox 允许输入数字及字母的工具类