WPF: Как стилизовать или отключить контекстное меню по умолчанию для TextBox

Очевидно, когда пользователи щелкают правой кнопкой мыши в нашем приложении WPF и используют классическую тему Windows, по умолчанию ContextMenu TextBox (который содержит Copy, Cut и Paste) имеет черный фон.

Я знаю, это хорошо работает:

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

Кто-нибудь знает, как стилизовать или отключить стандартное ContextMenu для всех TextBox в WPF?

13.08.2008 10:05:41
не нужно ли отключать сочетания клавиш, например, CTRL-V?
Carlos Liu 21.01.2016 03:00:49
6 ОТВЕТОВ

Попробуйте удалить атрибут x: Key из ресурса Style, оставив 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>
1
13.08.2008 14:12:04

Не имеет значения, если вы не предоставите ключ, он будет использовать TargetTypeкак ключ точно так же, как мой пример :)

Взято из MSDN по стилю:

Установка 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

2
16.10.2014 10:14:37

Чтобы стилизовать ContextMenu для всех TextBox, я бы сделал что-то вроде следующего:

Сначала в разделе ресурсов добавьте 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}" />

Надеюсь это поможет!

32
14.08.2008 02:33:22
Извините, что наткнулся на ошибку ... Я никогда не осознавал этого, но я не могу использовать команды ApplicationCommands вырезать, скопировать и вставить напрямую при частичном доверии. Это меню не будет работать при частичном доверии. Щелчок по пункту меню абсолютно ничего не делает .. Мне жаль, что потребовалось почти 18 месяцев, чтобы обнаружить;)
Arcturus 26.03.2010 13:01:05
Ваш ответ привел меня к моему новому решению: отключить меню с пустым меню. Еще раз спасибо за ваш ответ!
Arcturus 26.03.2010 13:01:50
РЕШЕНИЕ

Из-за позднего сообщения об ошибке мы обнаружили, что мы не можем напрямую использовать вставку и копирование ApplicationComands в частично доверенном приложении. Таким образом, использование этих команд в любой команде ваших элементов управления при выполнении будет абсолютно ничего не делать.

Так что, по сути, ответ Брэдса был почти там, он, конечно, выглядел правильно, то есть без черного фона, но не решал проблему.

Мы решили «удалить» меню, основываясь на ответе Брэда, примерно так:

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

И используйте это пустое контекстное меню так:

<Style TargetType="{x:Type TextBox}">
  <Setter Property="ContextMenu" Value="{StaticResource TextBoxContextMenu}" />
</Style>
8
26.03.2010 13:04:21
или вы можете использовать <ContextMenu x: Key = "key" Visibility = "Collapsed" />, что также работает.
joedotnot 17.06.2015 09:01:47
Кроме того, настройка IsEnabledContextMenu falseпозволяет избежать проблемы «зависания» фокуса, когда пользователь пытается щелкнуть правой кнопкой мыши.
James M 25.04.2016 21:53:28

Bizarre. ContextMenu="{x:Null}"не делает трюк.

Это делает, однако:

<TextBox.ContextMenu>
    <ContextMenu Visibility="Collapsed">
    </ContextMenu>
</TextBox.ContextMenu>
19
16.10.2014 10:12:12

Это то, что я всегда использую:

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

А также можете использовать:

       MyTextbox.ContextMenu.Visibility = Visibility.Hidden;
       MyTextbox.ContextMenu.Visibility = Visibility.Visble;
1
20.12.2018 07:57:40
Ответы только на код не приветствуются. Пожалуйста, нажмите на изменить и добавьте несколько слов, обобщающих, как ваш код решает вопрос, или, возможно, объясните, чем ваш ответ отличается от предыдущего ответа / ответов. Спасибо
Nick 20.12.2018 05:57:33
@ Cœur, это действительно круто. Я не видел этого раньше, но обязательно буду использовать его в будущем. Есть ли страница документации для таких полезных функций?
Nick 20.12.2018 06:25:00
Посмотрите сейчас, полезнее в некоторых случаях.
MrBi 20.12.2018 07:58:14