WPF: How to style or disable the default ContextMenu of a TextBox
Asked Answered
E

6

32

Apparantly when users right-click in our WPF application, and they use the Windows Classic theme, the default ContextMenu of the TextBox (which contains Copy, Cut and Paste) has a black background.

I know this works well:

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

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

  <TextBox ContextMenu="{x:Null}"/>

</Page>

But this doesn't work:

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

Does anyone know how to style or disable the default ContextMenu for all TextBoxes in WPF?

Elongate answered 13/8, 2008 at 10:5 Comment(1)
don't you need considering disable shortcut keys, e.g. CTRL-V?Volution
E
10

Due to a late bug report we discovered that we cannot use the ApplicationComands Cut Paste and Copy directly in a partial trusted application. Therefor, using these commands in any Commmand of your controls will do absolutely nothing when executed.

So in essence Brads answer was almost there, it sure looked the right way i.e. no black background, but did not fix the problem.

We decided to "remove" the menu based on Brads answer, like so:

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

And use this empty context menu like so:

<Style TargetType="{x:Type TextBox}">
  <Setter Property="ContextMenu" Value="{StaticResource TextBoxContextMenu}" />
</Style>
Elongate answered 26/3, 2010 at 13:4 Comment(2)
or you could use <ContextMenu x:Key="key" Visibility="Collapsed" />, which also works.Verditer
Additionally, setting IsEnabled on ContextMenu to false avoids issue of the focus "freezing" when user attempts to right click.Stodge
E
32

To style ContextMenu's for all TextBoxes, I would do something like the following:

First, in the resources section, add a ContextMenu which you plan to use as your standard ContextMenu in a textbox.
e.g.

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

Secondly, create a style for your TextBoxes, which uses the context menu resource:

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

Finally, use your text box as normal:

<TextBox />

If instead you want to apply this context menu to only some of your textboxes, do not create the style above, and add the following to your TextBox markup:

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

Hope this helps!

Extern answered 13/8, 2008 at 14:36 Comment(2)
I am sorry to stumble upon a bug.. I never realized it, but I cannot use the ApplicationCommands Cut, Copy and Paste directly in partial trust.. This menu will not work under partial trust. Clicking the menu item, does absolutely nothing.. I am sorry it took almost 18 months to discover ;)Elongate
Your answer has lead me to my new solution: disabling the menu with an empty menu.. Thanks again though for your answer!Elongate
C
22

Bizarre. ContextMenu="{x:Null}" doesn't do the trick.

This does, however:

<TextBox.ContextMenu>
    <ContextMenu Visibility="Collapsed">
    </ContextMenu>
</TextBox.ContextMenu>
Copal answered 14/8, 2010 at 20:15 Comment(0)
E
10

Due to a late bug report we discovered that we cannot use the ApplicationComands Cut Paste and Copy directly in a partial trusted application. Therefor, using these commands in any Commmand of your controls will do absolutely nothing when executed.

So in essence Brads answer was almost there, it sure looked the right way i.e. no black background, but did not fix the problem.

We decided to "remove" the menu based on Brads answer, like so:

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

And use this empty context menu like so:

<Style TargetType="{x:Type TextBox}">
  <Setter Property="ContextMenu" Value="{StaticResource TextBoxContextMenu}" />
</Style>
Elongate answered 26/3, 2010 at 13:4 Comment(2)
or you could use <ContextMenu x:Key="key" Visibility="Collapsed" />, which also works.Verditer
Additionally, setting IsEnabled on ContextMenu to false avoids issue of the focus "freezing" when user attempts to right click.Stodge
E
2

Doesn't matter, if you do not provide a key, it will use the TargetType as key just the same way my example uses :)

Taken from MSDN on 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/en-us/library/system.windows.style.targettype.aspx

Elongate answered 13/8, 2008 at 14:23 Comment(0)
M
2

This is way is what I always use:

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

And also can use:

           MyTextbox.ContextMenu.Visibility = Visibility.Hidden;
           MyTextbox.ContextMenu.Visibility = Visibility.Visble;
Metope answered 20/12, 2018 at 5:35 Comment(3)
Code-only answers are discouraged. Please click on edit and add some words summarising how your code addresses the question, or perhaps explain how your answer differs from the previous answer/answers. ThanksDupaix
@Cœur that's really cool. I hadn't seen that before but will definitely use it in future. Is there a doc page for such useful features?Dupaix
Take a look now, more useful in some cases.Metope
B
1

Try removing the x:Key attribute from the Style resource, leaving TargetType. I know, you're supposed to have that x:Key for a resource, but if you have it along with your TargetType the Key prevails.

Here's a sample style that I use in a project to skin all tooltips in one of my apps (this is in 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>
Brana answered 13/8, 2008 at 14:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.