When I add a dropshadow bitmap effect to a rectangle, the dropshadow takes into account the transparency of the rectangle (makes sense). Is there a way to render a dropshadow on a transparent rectangle 'as if' the rectangle were opaque? ie what would appear is a rectangle-shaped 'hole', with a dropshadow.
Here is the XAML for a transparent rectangle with a dropshadow - nothing is displayed:
<Rectangle Fill="Transparent" Margin="10" Width="100" Height="100">
<Rectangle.BitmapEffect>
<DropShadowBitmapEffect/>
</Rectangle.BitmapEffect>
</Rectangle>
Drop this into Kaxaml. It creates a transparent Rectangle of size 500x500, with a SystemDropShadowChrome Decorator. The drop shadow's clip is set to exclude the Rectangle's region.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas>
<theme:SystemDropShadowChrome Margin="0,0,5,5">
<Rectangle Width="500" Height="500" Fill="transparent"/>
<theme:SystemDropShadowChrome.Clip>
<CombinedGeometry GeometryCombineMode="Exclude">
<CombinedGeometry.Geometry1>
<RectangleGeometry Rect="0,0,505,505"/>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<RectangleGeometry Rect="0,0,500,500"/>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</theme:SystemDropShadowChrome.Clip>
</theme:SystemDropShadowChrome>
</Canvas>
</Page>
If you want your drop shadow to have rounded corners, then set the CornerRadius of the SystemDropShadowChrome to whatever (let's say 10), then Geometry1's Left and Top values to 10, then the RadiusX and RadiusY of each RectangleGeometry to 10.
I'd love to see better solution, but here is what I usually do (beware: creepy code ahead).
Wrap rectangle to three-four rectangles, and play with stroke color, making it darker and darker as it goes to original rectangle. Here is the code:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Rectangle
Width="106"
Height="106"
Stroke="#10000000"
StrokeThickness="1"/>
<Rectangle
Width="104"
Height="104"
Stroke="#5C000000"
StrokeThickness="1"/>
<Rectangle
Width="102"
Height="102"
Stroke="#AC000000"
StrokeThickness="1"/>
<Rectangle
Width="100"
Height="100"
Fill="Transparent"
Stroke="#FF000000"
StrokeThickness="1">
</Rectangle>
</Grid>
</Page>
This gives you:
alt text http://img521.imageshack.us/img521/7664/shadowo.jpg
Another approach would be with borders - it's better because you don't have to specify dimensions, when you put them inside Grid.
And the best approach (never seen implemented though): custom pixel shader, which makes what you want.
Well, here is one long-winded way to implement a rectangular 'drop-shadow' without using a bitmap effect. In this case the centre of the 'shadow rectangle' is coloured in, but it could be set to transparent to give you a 'halo' style drop shadow (i.e., equal all the way round - not offset)
<UserControl x:Class="RectShadow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib">
<UserControl.Resources>
<System:Double x:Key="CornerSize">5</System:Double>
<Color x:Key="ShadowColor">#60000000</Color>
<Color x:Key="TransparentColor">#00000000</Color>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Rectangle Width="{StaticResource CornerSize}" Height="{StaticResource CornerSize}">
<Rectangle.Fill>
<RadialGradientBrush Center="1,1" GradientOrigin="1,1" RadiusX="1" RadiusY="1">
<GradientStop Color="{StaticResource ShadowColor}"/>
<GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="2" Grid.Column="2" Width="{StaticResource CornerSize}" Height="{StaticResource CornerSize}">
<Rectangle.Fill>
<RadialGradientBrush Center="0,0" GradientOrigin="0,0" RadiusX="1" RadiusY="1">
<GradientStop Color="{StaticResource ShadowColor}"/>
<GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="0" Grid.Column="2" Width="{StaticResource CornerSize}" Height="{StaticResource CornerSize}">
<Rectangle.Fill>
<RadialGradientBrush Center="0,1" GradientOrigin="0,1" RadiusX="1" RadiusY="1">
<GradientStop Color="{StaticResource ShadowColor}"/>
<GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="2" Grid.Column="0" Width="{StaticResource CornerSize}" Height="{StaticResource CornerSize}">
<Rectangle.Fill>
<RadialGradientBrush Center="1,0" GradientOrigin="1,0" RadiusX="1" RadiusY="1">
<GradientStop Color="{StaticResource ShadowColor}"/>
<GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="1">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Offset="1" Color="{StaticResource ShadowColor}"/>
<GradientStop Color="{StaticResource TransparentColor}"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="1" Grid.Row="2">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Color="{StaticResource ShadowColor}"/>
<GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="1">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0">
<GradientStop Offset="1" Color="{StaticResource ShadowColor}"/>
<GradientStop Color="{StaticResource TransparentColor}"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="1" Grid.Column="2">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0">
<GradientStop Color="{StaticResource ShadowColor}"/>
<GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="1" Grid.Column="1">
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource ShadowColor}"/>
</Rectangle.Fill>
</Rectangle>
</Grid>
</UserControl>
wrap the rectangle in a border. and add a shadow to the border. you'll get the same effect.
Related
I am trying to customize a ribbon button.
I have drawn two ellipses with an arrow pointing downwards. I've put this in Windows resources so that I can use this style throughout the project by referencing it by its key name "RibbonButtonControlTemplateTest". However, when I execute the code below all I see displayed is a blank white window, why?
<Window x:Class="WpfApplication5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
xmlns:local="clr-namespace:WpfApplication5"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ControlTemplate x:Key="RibbonButtonControlTemplateTest" TargetType="{x:Type RibbonButton}">
<Grid>
<Ellipse>
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Green"/>
<GradientStop Offset="0.5" Color="White"/>
<GradientStop Offset="1" Color="Green"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Margin="10">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Offset="0" Color="Transparent"/>
<GradientStop Offset="0.5" Color="White"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ed:BlockArrow HorizontalAlignment="Stretch" Height="Auto" Margin="28.212,26.557,29.404,19.757" Orientation="Down" Width="Auto">
<ed:BlockArrow.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Green"/>
<GradientStop Offset="0.5" Color="White"/>
<GradientStop Offset="1" Color="Green"/>
</LinearGradientBrush>
</ed:BlockArrow.Fill>
</ed:BlockArrow>
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid x:Name="gridLeft" HorizontalAlignment="Left" Width="253.714">
<RibbonButton x:Name="ribbonButton" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100"
Content="{StaticResource RibbonButtonControlTemplateTest}">
</RibbonButton>
</Grid>
<Grid x:Name="gridRight" HorizontalAlignment="Right" Width="253.714">
</Grid>
</Grid>
You use content instead template. Try to change this code:
<RibbonButton x:Name="ribbonButton" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100"
Content="{StaticResource RibbonButtonControlTemplateTest}">
</RibbonButton>
To:
<RibbonButton x:Name="ribbonButton" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100"
Template="{StaticResource RibbonButtonControlTemplateTest}">
</RibbonButton>
How is this normally handled? I have this xaml:
<Border Grid.Column="1" HorizontalAlignment="Right"
VerticalAlignment="Top" Margin="10,25,10,0" Opacity="0.7"
BorderBrush="Black" BorderThickness="1" CornerRadius="5">
<StackPanel>
<StackPanel.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="LightGray" Offset="0.0" />
<GradientStop Color="Gray" Offset="1.0" />
</LinearGradientBrush>
</StackPanel.Background>
The top left and right corners of the StackPanel are LightGray, and appear to be on top of the Border, so that in the middle of the rounded Black corners is a LightGray pixel or two, breaking up the rounding. The bottom border is Gray instead of Black.
What I thought I would get with the code above is a StackPanel with rounded corners...
I would suggest putting the background on the Border and not the Stackpanel
<Border Grid.Column="1" HorizontalAlignment="Right"
VerticalAlignment="Top" Margin="10,25,10,0" Opacity="0.7"
BorderBrush="Black" BorderThickness="1" CornerRadius="5">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="LightGray" Offset="0.0" />
<GradientStop Color="Gray" Offset="1.0" />
</LinearGradientBrush>
</Border.Background>
<StackPanel>
<!-- Items here -->
</StackPanel>
</Border>
Using a RadialGradientBrush is simple and allows a center colour to merge into an outer colour. This works fine as a brush for filling the inside of a Rectangle or Border. I want to achieve the effect of applying that brush as if it were a pen and apply it as the Border.BorderBrush. So the center of the border would be dark and away from the border it would fade away.
Another way to describe it is the shadow you see around top level windows on Windows Vista or Windows 7. Close to the window border the shadow is dark and the further away you go from the window the more the shadow fades away. Well I want to draw a Border in a similar way.
I cannot find any way to achieve this at the moment, using either the RadialGradientBrush or the LinearGradientBrush. Surely it must be possible? Any ideas?
You could achieve an effect like this
by placing your content in the center (cell 1,1) of a 3x3 Grid like this:
<Grid>
<Grid.Resources>
<Color x:Key="InnerColor">#FF000000</Color>
<Color x:Key="OuterColor">#FFFFFFFF</Color>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition />
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Rectangle Grid.Column="1" Grid.Row="0">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="{StaticResource OuterColor}"/>
<GradientStop Offset="1" Color="{StaticResource InnerColor}"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="1" Grid.Row="2">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="{StaticResource InnerColor}"/>
<GradientStop Offset="1" Color="{StaticResource OuterColor}"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="0" Grid.Row="1">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="{StaticResource OuterColor}"/>
<GradientStop Offset="1" Color="{StaticResource InnerColor}"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="2" Grid.Row="1">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="{StaticResource InnerColor}"/>
<GradientStop Offset="1" Color="{StaticResource OuterColor}"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="0" Grid.Row="0">
<Rectangle.Fill>
<RadialGradientBrush GradientOrigin="1,1" Center="1,1" RadiusX="1" RadiusY="1">
<GradientStop Offset="0" Color="{StaticResource InnerColor}"/>
<GradientStop Offset="1" Color="{StaticResource OuterColor}"/>
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="2" Grid.Row="0">
<Rectangle.Fill>
<RadialGradientBrush GradientOrigin="0,1" Center="0,1" RadiusX="1" RadiusY="1">
<GradientStop Offset="0" Color="{StaticResource InnerColor}"/>
<GradientStop Offset="1" Color="{StaticResource OuterColor}"/>
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="0" Grid.Row="2">
<Rectangle.Fill>
<RadialGradientBrush GradientOrigin="1,0" Center="1,0" RadiusX="1" RadiusY="1">
<GradientStop Offset="0" Color="{StaticResource InnerColor}"/>
<GradientStop Offset="1" Color="{StaticResource OuterColor}"/>
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="2" Grid.Row="2">
<Rectangle.Fill>
<RadialGradientBrush GradientOrigin="0,0" Center="0,0" RadiusX="1" RadiusY="1">
<GradientStop Offset="0" Color="{StaticResource InnerColor}"/>
<GradientStop Offset="1" Color="{StaticResource OuterColor}"/>
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
You could try and use a Grid or a DockPanel and then use Line or Rectangle to create 4 filled distinct regions. However, you can't use a RadialGradient in this case because it will stretch, and look wrong. So instead you could create 4 different LinearGradients which were setup to graduate in the 4 different directions you want.....however, I don't think this would look right either in the corners...as they need to be mitred...and this won't do that.
So...
...you could try and use this GradientPath control that knows how to draw a gradient along a path.
http://www.charlespetzold.com/blog/2009/02/Graphical-Paths-with-Gradient-Colors.html
Note, I haven't been able to spend much time with it so I haven't worked out how to use it properly - the start and end caps of the rectangle aren't quite right.
Note using a PathGeometry instead of RectangleGeometry still has the same problem.
One possible workaround is to create 2 rectangles with GradientPath and then cut them through the diagonal (using a suitable Clip definition) so that they each contribute the good part of the rectangle (i.e. without the start/end artifact)...and overlay them in a Grid.
Or you could dig into the GradientPath code.
It should give you some ideas if you want to take this approach....and play around/experiment at your leisure till it is how you want it.
<gpl:GradientPath Name="gradientPath2"
StrokeThickness="30"
>
<gpl:GradientPath.Data>
<RectangleGeometry Rect="0,0,200,200" />
</gpl:GradientPath.Data>
<gpl:GradientPath.GradientStops>
<GradientStop Offset="0" Color="Blue" />
<GradientStop Offset="0.5" Color="Red" />
<GradientStop Offset="1" Color="Green" />
</gpl:GradientPath.GradientStops>
</gpl:GradientPath>
I have a Rectangle with rounded corners (but not an ellipse), something like this:
<Rectangle Stroke="Black" StrokeThickness="2" RadiusX="50" RadiusY="100">
<Rectangle.Fill>
<RadialGradientBrush RadiusY="0.5">
<GradientStop Color="Black" Offset="1" />
<GradientStop Color="White" Offset="0.8" />
</RadialGradientBrush>
</Rectangle.Fill>
</Rectangle>
I want to use a gradient fill from black to white. How can I specify this in order to make the fill keep the shape of the rounded rectangle, instead of being an ellipse?
For a rounded rectangle you can do it all in XAML using radial gradients for the corners and linear gradients for the sides.
The example uses a ViewBox so the Size doesn't need to be set both on the grid and its clip path. If you need it to resize keeping the same border radius you could bind RectangleGeometry.Rect and use a ValueConverter. The gradient and the RadiusX and RadiusY properties can be easily changed in one place.
<Viewbox Stretch="Fill">
<Grid Width="100" Height="100">
<Grid.Resources>
<Color x:Key="inside">White</Color>
<GradientStopCollection x:Key="gradient">
<GradientStop Color="Black" Offset="1"/>
<GradientStop Color="{DynamicResource inside}" Offset="0.2"/>
</GradientStopCollection>
</Grid.Resources>
<Grid.Clip>
<RectangleGeometry RadiusX="15" RadiusY="30" Rect="0,0,100,100" x:Name="clip" />
</Grid.Clip>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding RadiusX, ElementName=clip}" />
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="{Binding RadiusX, ElementName=clip}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding RadiusY, ElementName=clip}"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="{Binding RadiusY, ElementName=clip}"/>
</Grid.RowDefinitions>
<Rectangle Grid.Column="1" Margin="-1,0">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0,0" MappingMode="RelativeToBoundingBox" StartPoint="0,1" GradientStops="{DynamicResource gradient}" />
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="2" Grid.Row="1" Margin="0,-1">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0" MappingMode="RelativeToBoundingBox" StartPoint="0,0" GradientStops="{DynamicResource gradient}" />
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="1" Grid.Row="2" Margin="-1,0">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0" GradientStops="{DynamicResource gradient}" />
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="1" Margin="0,-1">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0,0" MappingMode="RelativeToBoundingBox" StartPoint="1,0" GradientStops="{DynamicResource gradient}" />
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="1" Grid.Row="1" Margin="-1">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource inside}" />
</Rectangle.Fill>
</Rectangle>
<Rectangle>
<Rectangle.Fill>
<RadialGradientBrush Center="1,1" RadiusX="1" RadiusY="1" GradientOrigin="1,1" GradientStops="{DynamicResource gradient}" />
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="2">
<Rectangle.Fill>
<RadialGradientBrush Center="0,1" RadiusX="1" RadiusY="1" GradientOrigin="0,1" GradientStops="{DynamicResource gradient}" />
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="2" Grid.Row="2">
<Rectangle.Fill>
<RadialGradientBrush Center="0,0" RadiusX="1" RadiusY="1" GradientOrigin="0,0" GradientStops="{DynamicResource gradient}" />
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="2">
<Rectangle.Fill>
<RadialGradientBrush Center="1,0" RadiusX="1" RadiusY="1" GradientOrigin="1,0" GradientStops="{DynamicResource gradient}" />
</Rectangle.Fill>
</Rectangle>
</Grid>
</Viewbox>
If you need to a gradient to follow more complex shapes you can do it with a V3.0 PixelShader.
Here is a simple example composing a rounded-rectangle gradient out of more primitive gradients:
<Canvas>
<Canvas.Resources>
<GradientStopCollection x:Key="stops">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Black" Offset="1"/>
</GradientStopCollection>
<RadialGradientBrush x:Key="cornerBrush" GradientStops="{StaticResource stops}"/>
<LinearGradientBrush x:Key="topBrush" StartPoint="0,1" EndPoint="0,0" GradientStops="{StaticResource stops}"/>
<LinearGradientBrush x:Key="leftBrush" StartPoint="1,0" EndPoint="0,0" GradientStops="{StaticResource stops}"/>
<LinearGradientBrush x:Key="rightBrush" StartPoint="0,0" EndPoint="1,0" GradientStops="{StaticResource stops}"/>
<LinearGradientBrush x:Key="bottomBrush" StartPoint="0,0" EndPoint="0,1" GradientStops="{StaticResource stops}"/>
</Canvas.Resources>
<Ellipse Canvas.Left="0" Canvas.Top="0" Width="100" Height="100" Fill="{StaticResource cornerBrush}"/>
<Ellipse Canvas.Left="200" Canvas.Top="0" Width="100" Height="100" Fill="{StaticResource cornerBrush}"/>
<Ellipse Canvas.Left="0" Canvas.Top="200" Width="100" Height="100" Fill="{StaticResource cornerBrush}"/>
<Ellipse Canvas.Left="200" Canvas.Top="200" Width="100" Height="100" Fill="{StaticResource cornerBrush}"/>
<Rectangle Canvas.Left="50" Canvas.Top="0" Width="200" Height="50" Fill="{StaticResource topBrush}"/>
<Rectangle Canvas.Left="0" Canvas.Top="50" Width="50" Height="200" Fill="{StaticResource leftBrush}"/>
<Rectangle Canvas.Left="250" Canvas.Top="50" Width="50" Height="200" Fill="{StaticResource rightBrush}"/>
<Rectangle Canvas.Left="50" Canvas.Top="250" Width="200" Height="50" Fill="{StaticResource bottomBrush}"/>
<Rectangle Canvas.Left="50" Canvas.Top="50" Width="200" Height="200" Fill="White"/>
</Canvas>
which produces this effect:
I want to set background of a grid using a style. I style I'm setting the Background Property of the grid.
But I have a border filled with LinearGradientFill and a Path which also has LinearGradientFill in it.
But I'm not able to combine both.
Below is sample code. I want to create it as a style.
<Grid>
<Border BorderBrush="Black" BorderThickness="2">
<Border.Background>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="Black" Offset="0.953" />
<GradientStop Color="White" Offset="0" />
</LinearGradientBrush>
</Border.Background>
</Border>
<Path Data="M 0,0 C 0,620 10,10 560,0" Height="60" VerticalAlignment="Top">
<Path.Fill>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="Black" Offset="0" />
<GradientStop Color="White" Offset="0.779" />
</LinearGradientBrush>
</Path.Fill>
</Path>
</Grid>
It gives me an error as:
The Property 'Value' is set more than once.
Archie,
You need to use a Template in order to place arbitrary XAML into a Style. Unfortuately, only Controls have Templates, and Grids and Borders are not Controls. But there is a solution. Although not as clean as you would like, the following XAMl should accomplish your goal. You paste the following XAML into Charles Petzold's XAML Cruncher to see the results:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="400">
<UserControl.Resources>
<!-- A ContentControl template that defines your background -->
<ControlTemplate x:Key="BackgroundTemplate" TargetType="ContentControl">
<Grid>
<Border BorderBrush="Black" BorderThickness="2">
<Border.Background>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="Black" Offset="0.953" />
<GradientStop Color="White" Offset="0" />
</LinearGradientBrush>
</Border.Background>
</Border>
<Path Data="M 0,0 C 0,620 10,10 560,0" Height="60" VerticalAlignment="Top">
<Path.Fill>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="Black" Offset="0" />
<GradientStop Color="White" Offset="0.779" />
</LinearGradientBrush>
</Path.Fill>
</Path>
</Grid>
</ControlTemplate>
<!-- A ContentControl Style that references the background template -->
<Style x:Key="BackgroundStyle" TargetType="ContentControl">
<Setter Property="Template" Value="{StaticResource BackgroundTemplate}" />
</Style>
</UserControl.Resources>
<!-- Typical usage; place the background ContentControl behind your body content -->
<Grid x:Name="LayoutRoot">
<ContentControl Style="{StaticResource BackgroundStyle}" />
<TextBlock Text="Your Content" Foreground="Red" FontSize="36" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</UserControl>