ВПФ:Как стилизовать или отключить контекстное меню по умолчанию для текстового поля

StackOverflow https://stackoverflow.com/questions/9632

  •  08-06-2019
  •  | 
  •  

Вопрос

Очевидно, когда пользователи щелкают правой кнопкой мыши в нашем приложении WPF и используют тему Windows Classic, контекстное меню TextBox по умолчанию (которое содержит команды «Копировать», «Вырезать» и «Вставить») имеет черный фон.

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

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

Это было полезно?

Решение 3

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

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

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

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

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

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

Другие советы

Чтобы стилизовать 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}" />

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

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

Однако это имеет место:

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

Попробуйте удалить атрибут x:Key из ресурса Style, оставив TargetType.Я знаю, что у вас должен быть этот x:Key для ресурса, но если он у вас есть вместе с вашим TargetType, ключ имеет преимущественную силу.

Вот пример стиля, который я использую в проекте для оформления всех всплывающих подсказок в одном из моих приложений (это в 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 в стиле:

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

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

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

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

       MyTextbox.ContextMenu.Visibility = Visibility.Hidden;
       MyTextbox.ContextMenu.Visibility = Visibility.Visble;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top