WPF:如何设置或者禁用文本框的默认ContextMenu

时间:2020-03-05 18:39:21  来源:igfitidea点击:

显然,当用户在我们的WPF应用程序中单击鼠标右键,并且使用Windows Classic主题时,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?

解决方案

回答

尝试从Style资源中删除x:Key属性,并保留TargetType。我知道,我们应该为资源使用x:Key,但是如果我们将它与TargetType一起使用,则以Key为准。

这是我在项目中使用的示例样式,用于对我的一个应用程序中的所有工具提示进行外观设置(这在App.Resources中-注意,无键)

<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>

回答

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

取自MSDN上的Style:

Setting the TargetType property to the TextBlock type without
  setting an x:Key implicitly sets the x:Key to {x:Type TextBlock}. This also means that if you > > give the above Style an x:Key value of anything other than {x:Type TextBlock}, the Style
  would not be applied to all TextBlock elements automatically. Instead,
  you need to apply the style to the TextBlock elements explicitly.

http://msdn.microsoft.com/zh-CN/library/system.windows.style.targettype.aspx

回答

要为所有TextBox设置ContextMenu的样式,我将执行以下操作:

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

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

其次,为TextBoxes创建一种样式,该样式使用上下文菜单资源:

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

最后,照常使用文本框:

<TextBox />

相反,如果我们只想将此上下文菜单仅应用于某些文本框,则不要创建上面的样式,而是将以下内容添加到TextBox标记中:

<TextBox ContextMenu="{StaticResource TextBoxContextMenu}" />

希望这可以帮助!

回答

由于最新的错误报告,我们发现我们不能在部分受信任的应用程序中直接使用ApplicationComands剪切粘贴和复制。因此,在任何命令中使用这些命令在执行时绝对没有任何作用。

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

我们决定根据Brads答案"删除"菜单,如下所示:

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

并像下面这样使用此空上下文菜单:

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

回答

怪异的ContextMenu =" {x:Null}"不能解决问题。

但是,这样做:

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