Create a visual template for grid - wpf

I am trying to create a visual template (saved in resource dictionary as xaml code) for a grid object, that I will apply to various grid objects created later in runtime.
I need a simple style with border and background.
What would be the best way of doing this?
Simple working examples would be greatly appreciated.
Ok, so, after searching for examples, I tried something like this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="TestStyle">
<Setter Property="Background" Value="#FF873507" />
<Setter.Value>
<ControlTemplate>
<Grid>
<Border BorderThickness="7" CornerRadius="4">
<Border.BorderBrush>
<SolidColorBrush Color="#73B2F5"/>
</Border.BorderBrush>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Style>
</ResourceDictionary>

WPF doesn't really work like that... because the Grid class has no Template property, you cannot define a new ControlTemplate for it. The nearest thing that you can do is to create a UserControl with the UI elements that you want to use and then display the UserControl wherever you want to display those controls.
Alternatively, you could define your content inside a ControlTemplate if the inner controls will always be the same:
<ControlTemplate x:Key="StaticGrid">
<Grid>
<Border BorderThickness="7" CornerRadius="4">
<Border.BorderBrush>
<SolidColorBrush Color="#73B2F5"/>
</Border.BorderBrush>
<!--Add your inner elements here-->
</Border>
</Grid>
</ControlTemplate>
You could then display it like this:
<ContentControl Template="{StaticResource StaticGrid}" />
However, you wouldn't be able to add different inner elements using this method. If you used the UserControl method, you could potentially replace the word UserControl with Grid so that you were in fact extending the Grid class, but you still wouldn't be able to add different elements to it.
The best that you could do in a Style would be to set the Background property.

After more tries and frustrations, I found a much simpler solution, that worked for me.
Instead of trying to apply the style to the grid, I applied it to the border around the grid.
So, my dictionary looks like this:
<Style x:Key="TestStyle" TargetType="{x:Type Border}">
<Setter Property="Background" Value="#FFBDACA2" />
<Setter Property="BorderBrush" Value="#FFFF5E00" />
<Setter Property="CornerRadius" Value="30,30,30,30" />
<Setter Property="BorderThickness" Value="10" />
</Style>
And my main frame xaml:
<Border Style="{StaticResource TestStyle}" >
<Grid>
</Grid>
</Border>

Related

WPF themeing best practices

This is a best practices question regarding wpf themeing and more specifically skinning.
This is more of an opinion based question since I don't have a problem making this work but more of a general wondering if my conclusions cover all the scenarios, and if any one else came across the same thoughts on the issue and what was their approach .
Some background, Our team is required to define a way to give our system the ability to be themeable.
We broke this ability down to 2 categories :
1) The styles of our controls which we simply call 'Theme'.
2) The resources they use to customize their appearance called 'Skin' this includes Brushes , and all sorts of sizing structs like CornerRadius , BorderThickness etc.
The way which a Skin is set for the system is a simple case of merging the skin dictionary last into our app's resources.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Default.skin.xaml" />
<ResourceDictionary Source="Theme.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
A different skin being merged last into our app.
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
string skin = e.Args[0];
if (skin == "Blue")
{ .
ResourceDictionary blueSkin = new ResourceDictionary();
blueSkin.Source = new Uri("Blue.skin.xaml", UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Add(blueSkin);
}
}
Inside Theme.xaml :
<!-- Region TextBox ControlTemplate -->
<ControlTemplate TargetType="{x:Type TextBox}" x:Key="TextBoxTemplate">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{StaticResource TextBoxCornerRadius}" >
<Border x:Name="shadowBorder" BorderBrush="{StaticResource TextBoxShadowBrush}"
CornerRadius="{StaticResource TextBoxInnerShadowCornerRadius}"
BorderThickness="{StaticResource TextBoxInnerShadowBorderThickness}"
Margin="{StaticResource TextBoxInnerShadowNegativeMarginForShadowOverlap}" >
<ScrollViewer x:Name="PART_ContentHost" Padding="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" />
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="BorderThickness" Value="0">
<Setter TargetName="shadowBorder" Property="BorderThickness" Value="0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- EndRegion -->
<!-- Region TextBox Style -->
<Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}">
<Setter Property="BorderBrush" Value="{StaticResource TextBoxBorderBrush}" />
<Setter Property="Background" Value="{StaticResource TextBoxBackgroundBrush}" />
<Setter Property="BorderThickness" Value="{StaticResource TextBoxBorderThickness}" />
<Setter Property="Padding" Value="{StaticResource TextBoxPadding}" />
<Setter Property="Template" Value="{StaticResource TextBoxTemplate}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource TextBoxIsMouseOverBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource TextBoxIsMouseOverBorderBrush}" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="{StaticResource TextBoxIsMouseWithinBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource TextBoxIsMouseWithinBorderBrush}" />
</Trigger>
</Style.Triggers>
</Style>
<!-- EndRegion -->
In the TextBox ControlTemplate there are elements bound to DependencyProperties using TemplateBinding and some like the CornerRadius and InnerCornerRadius, InnerBorderThickness and InnerBorderBrush which are given their value from resources.
What would be the best approach ?
creating a derived control with the relevant Dependency properties
which would reference the relevant resources and then have the elements in the control template bind to them.
Or
have the elements inside the template reference these resources themselves.
Using the Dependency Property approach :
Advantages :
1) Clarity, we have a clearer API for our control and better understanding of how our control looks and behaves the way it does.
2) The template does not have to change in order to be customizable. Everything is controlled via style.
3) Triggers as well change the look and feel of the control without the need to override the control template, no need for ControlTemplate triggers.
4) "Blendabilty" using blend i can much easily customize my control.
5) Styles themselves are inheritable. so if i want to change just one aspect of the control all i need to do is inherit from the default style.
Disadvantages :
1) Implementing yet another custom control.
2) Implementing numerous dependency properties, some of which do not have much to do with the control and are only there to satisfy something we have in our template.
Just to clarify this means inheriting from TextBox something like InnerShadowTextBox and
implementing dependency properties with in it for all the above.
This will intensify if I have numerous elements inside my template which have to be customizable.
Something like this monstrosity:
<Style x:Key="{x:Type cc:ComplexControl}" TargetType="{x:Type cc:ComplexControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type cc:ComplexControl}">
<Grid>
<Ellipse Fill="Red" Margin="0" Stroke="Black" StrokeThickness="1"/>
<Ellipse Fill="Green" Margin="6" Stroke="Red" StrokeThickness="1"/>
<Ellipse Fill="Blue" Margin="12"/>
<Ellipse Fill="Aqua" Margin="24" />
<Ellipse Fill="Beige" Margin="32"/>
<StackPanel Orientation="Horizontal" Width="25" Height="25"
VerticalAlignment="Center" HorizontalAlignment="Center">
<Rectangle Fill="Black" Width="2" />
<Rectangle Fill="Black" Width="2" Margin="2,0,0,0"/>
<Rectangle Fill="Black" Width="2" Margin="2,0,0,0"/>
<Rectangle Fill="Black" Width="2" Margin="2,0,0,0"/>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Which would require numerous resources :
<SolidColorBrush x:Key="Ellipse1Fill">Red</SolidColorBrush>
<SolidColorBrush x:Key="Ellipse2Fill">Green</SolidColorBrush>
<SolidColorBrush x:Key="Ellipse3Fill">Blue</SolidColorBrush>
<SolidColorBrush x:Key="Ellipse4Fill">Aqua</SolidColorBrush>
<SolidColorBrush x:Key="Ellipse5Fill">Beige</SolidColorBrush>
<SolidColorBrush x:Key="Ellipse1Stroke">Beige</SolidColorBrush>
<sys:Double x:Key="Ellipse1StrokeThickness>1</sys:Double>
......... and many more
I would have a large list of resources either way. But with dependency properties.
I would also need to assign need to find meaning in every little part,Which sometimes isn't much more then "it looks good" and does not have much to do with the control or What if tomorrow I would want to change the template.
Using the approach where the resources are referenced from within the control template.
Advantages :
1) Easy to use, side steps the ugliness describes in the disadvantages described above in the Dp approach while providing a "hack" that enables a theme.
Disadvantages :
1) If I would want to further customize my control like add a trigger that influences the inner border of my TextBox I would simply have to create a new control template.
2) Not a clear API, Lets say I would like to change the BorderBrush of the inner border in a specific view.
<TextBox>
<TextBox.Resources>
<SolidColorBrush x:Key="InnerBorderBrush" Color="Red" />
</TextBox.Resources>
</TextBox>
Which isn't that bad come to think about it…
we sometimes do this with Selector implementations which internally use the specific resources when getting rid of the inactive selection and hightlight colors like so :
<ListBox>
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}" Color="Transparent"/>
</ListBox.Resources>
</ListBox>
Conclusions :
The hybrid described in the TextBox Style above is the way to go.
1) Dependency properties will be introduced only for aspects of the control which relate to the control's logic including specific template part's .
2) The resource names would be comprised by a clear naming convention and separated in files based on the control they relate to and common usages in views,Like Common brushes used in views in our app.
3) Control templates should aspire to be minimalistic and to use existing Dependency properties. Like Background, Foreground, BorderBrush etc.
I would greatly appreciate your input and thoughts on the matter , thanks in advance.
As Xavier said, this might be a better question for Code Review. But I will convey some key thoughts on your question, even though a lot of it will come to personal (or team) style and requirements.
After creating several dozen themes, I would recommend against custom controls whenever possible. Over time, the maintainability goes down quite a bit.
If you require minor modifications to a style, it is better to use DataTemplates and Data Triggers if the situation allows. This way you are changing the style in a clean way.
Additionally, you can leverage the BasedOn property. Create your "base" style and have multiple styles that have the attribute BasedOn="{myBaseStyle}. This will allow you lots of options without cluttering your code.
As a rule of thumb, I always recommend having more brushes/colors/resources as opposed to more styles or templates. We usually have our hierarchy set for colors->brushes->styles->templates. This helps reuse the colors while still maintaining separation via brushes.
Using DynamicResource as opposed to StaticResource is also useful in some situations where you load resources dynamically.
Hope this helps. Would love to write more, but some of the parameters for writing a solid theme is very context specific. If you have further examples, I'd be glad to add more information.

Setter in property trigger fails if target property already has an explicit value

I'm currently trying to create a ControlTemplate for the Button class in WPF, replacing the usual visual tree with something that makes the button look similar to the little (X) close icon on Google Chrome's tabs. I decided to use a Path object in XAML to achieve the effect. Using a property trigger, the control responds to a change in the IsMouseOver property by setting the icon's red background.
Here's the XAML from a test app:
<Window x:Class="Widgets.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style x:Key="borderStyle" TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#CC0000"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<ControlTemplate x:Key="closeButtonTemplate" TargetType="Button">
<Border Width="12" Height="12" CornerRadius="6"
BorderBrush="#AAAAAA" Background="Transparent"
Style="{StaticResource borderStyle}"
ToolTip="Close">
<Viewbox Margin="2.75">
<Path Data="M 0,0 L 10,10 M 0,10 L 10,0" Stroke="{Binding BorderBrush, RelativeSource={RelativeSource FindAncestor, AncestorType=Border, AncestorLevel=1}}" StrokeThickness="1.8"/>
</Viewbox>
</Border>
</ControlTemplate>
</Window.Resources>
<Grid Background="White">
<Button Template="{StaticResource closeButtonTemplate}"/>
</Grid>
</Window>
Note that the circular background is always there - it's just transparent when the mouse isn't over it.
The problem with this is that the trigger just isn't working. Nothing changes in the button's appearance. However, if I remove the Background="Transparent" value from the Border object in the ControlTemplate, the trigger does work (albeit only when over the 'X').
I really can't explain this. Setters for any other properties placed in the borderStyle resource work fine, but the Background setter fails as soon as the default background is specified in the ControlTemplate.
Any ideas why it's happening and how I can fix it? I know I could easily replace this code with, for example, a .PNG-based image, but I want to understand why the current implementation isn't working.
Thanks! :)
Try moving the explict "Background" assignment from inside the Border declaration to the Style itself:
<Style x:Key="borderStyle" TargetType="Border">
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#CC0000"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
...
<Border Width="12" Height="12" CornerRadius="6"
BorderBrush="#AAAAAA"
Style="{StaticResource borderStyle}"
ToolTip="Close">
Styles can't override a property that has been explicitly set. You need to set the value in the style.
I think your problem is that the Border does not 'catch' the mouse events when it is transparant.
To verify - try changing the background to #01FFFFFF instead of Transparent.

Silverlight custom control's content in scrollviewer

I have a Silverlight control derived from ContentControl.
I use it in following way
<local:CustomControl>
<local:AnotherControl>
</local:CustomControl>
I want to have the content (i.e. AnotherControl) in a ScrollViewer.
Without changing the above XAML usage, how can I have the content in scrollviewer? What modification do I need to make in CustomControl's template?
Thanks
I found the way to do this
I defined control template as following
<Style TargetType="local:MyCustomControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyCustomControl">
<ScrollViewer>
<Canvas>
<ContentPresenter/>
</Canvas>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Its working for me. Is it the proper way?

Styling a WPF layout grid background (of each cell, row, column)

I would like to know if there is any way to style a WPF layout grid's cells, rows and columns. I've been trying to find any information and the few mentions I've found have not been that informative.
I would like to style the grid to look like the one in the linked screenshot.
If the actual control does not support it, can I inherit it somehow and do it then? I am quite new to WPF so any help would be very appreciated.
One other thing, I know I can style each and every control within the grid, but it seems like overkill. I would like to have a grid that does it itself.
screenshot http://img21.imageshack.us/img21/2842/capturehz8.png
#Dan recommends WPF Unleashed, which I'm currently reading. Just this morning, I come across a section addressing your question.
Chapter 6, Page 161:
FAQ: How can I give Grid cells background colors, padding, and borders like I can with cells of a HTML Table?
There is no intrinsic mechanism to give Grid cells such properties, but you can simulate them pretty easily thanks to the fact that multiple elements can appear in any Grid cell. To give a cell a background color, you can simply plop in a Rectangle with the appropriate Fill, which stretches to fill the cell by default. To give a cell padding, you can use auto sizing and set the Margin on the appropriate child element. For borders, you can again use a Rectangle but give it an explicit Stroke of the appropriate color, or you can simply use a Border element instead.
Just be sure to add such Rectangles or Borders to the Grid before any of the other children (or explicitly mark them with the ZIndex attached property), so their Z order puts them behind the main content.
Btw, WPF Unleashed rocks. Its very well written, and the print in full color makes it even more easier to read.
Here's a quick (very rough sample) that you could hack around to get the format you want (if you're serious about working with WPF, you'll find Blend an enormous help in getting your layouts looking good):
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="CustomerDefinition" TargetType="TextBlock">
<Setter Property="Control.FontFamily" Value="Tahoma"/>
<Setter Property="Control.FontSize" Value="12"/>
<Setter Property="Control.Foreground" Value="Red"/>
</Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Width" Value="100"/>
</Style>
<Style x:Key="{x:Type TextBox}" TargetType="{x:Type TextBox}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="Width" Value="200"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border
Name="Border"
Background="#FFEBE9E9"
BorderBrush="#FF8B8787"
BorderThickness="1"
CornerRadius="2"
Padding="3">
<ScrollViewer x:Name="PART_ContentHost" Margin="0"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background"
Value="#EEEEEE"/>
<Setter TargetName="Border" Property="BorderBrush"
Value="#EEEEEE"/>
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0.0" Color="#FFF0EDED"/>
<GradientStop Offset="1.0" Color="#FFE1E0E0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
</Page.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="26"/>
<RowDefinition Height="23"/>
<RowDefinition Height="24"/>
<RowDefinition Height="24"/>
<RowDefinition Height="24"/>
</Grid.RowDefinitions>
<TextBlock
Grid.ColumnSpan="2"
Grid.Row="0"
Style="{StaticResource CustomerDefinition}"
Text="Customer Definition"/>
<Border
Grid.Column="0"
Grid.Row="1"
Background="#FFEBE9E9"
BorderBrush="#FF8B8787"
BorderThickness="1">
<StackPanel Background="{StaticResource NormalBrush}" Orientation="Horizontal">
<Label Content="Customer Code"/>
<TextBox Text="SMITHA 098 (normally I'd bind here)"/>
</StackPanel>
</Border>
<Border
Grid.Column="1"
Grid.Row="1"
Background="#FFEBE9E9"
BorderBrush="#FF8B8787"
BorderThickness="1">
<StackPanel Background="{StaticResource NormalBrush}" Orientation="Horizontal">
<Label Content="Customer Type"/>
<TextBox Text="PRIVATE INDIVIDUAL"/>
</StackPanel>
</Border>
</Grid> </Page>
The WPF Grid doesn't have visible cells as such. Think of them as invisible grid lines against which you can have child elements be aligned.
So, to style the grid's cells, you have to style the items that are aligned inside the grid.
It is confusing to think of the Grid as being anything like a WinForms DataGrid. I guess its closest WinForms equivalent is the TableLayout control.
Check out some 3rd party grid controls. I used the DevExpress one while it was in beta and found it pretty straightforward.
I would recommend using borders for your styling.
You could recreate that layout pretty easily by creating borders for each row and each column and set the rowspans and colspans accordingly.
You will have 5 borders with colspan 2, these borders will take care of your gradient backgrounds for each row and the borders along the top and bottom of each row. Then you will have 2 borders with rowspan 5 these will handle the column borders. Imagine that you are overlaying the borders to form the visual grid effect you are after.
For the header and outer border, just wrap the entire grid with a border and style as needed.
I would recommend storing your styles as resources so you can keep all your styling info in one place.
Take care to learn how the styling works because it is pretty powerful, but there is a learning curve as it is quite different to the way CSS works. I would recommend reading WPF Unleashed if you can.
I found this post when looking for method for setting margin (or padding) for DataGrid cells. My problem was solved thanks to example xaml code posted at (near the end) -- pretty minimalistic.
http://forums.silverlight.net/forums/p/16842/55997.aspx

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

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?
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!
Bizarre. ContextMenu="{x:Null}" doesn't do the trick.
This does, however:
<TextBox.ContextMenu>
<ContextMenu Visibility="Collapsed">
</ContextMenu>
</TextBox.ContextMenu>
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>
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
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;
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>

Resources