RadialGradientBrush on Rounded-Corner Rectangle - wpf

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:

Related

WPF deforms opacity mask

I'm trying to achieve this:
The gradient proportion will grow so I did a circle as opacityMask then a recangle using the circle as mask, like that:
<Ellipse Name="Mask"
Fill="Red"
Width="{Binding ActualWidth, ElementName=mainGrid}" Grid.ColumnSpan="3"
Visibility="Visible"/>
<Rectangle Name="Gradient" Fill="Azure"
Grid.Column="2" Width="100"
HorizontalAlignment="Left"
VerticalAlignment="Stretch">
<Rectangle.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Mask}" />
</Rectangle.OpacityMask>
</Rectangle>
and I get this:
How do I keep the rectangle's form and mask it using the circle ??
This should work:
<VisualBrush Visual="{Binding ElementName=Mask}"
Stretch="None" AlignmentX="Left" AlignmentY="Top"/>
So you need something like this:
<Border Name="Mask"
Background="White"
Grid.Column="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
</Border>
<Ellipse Name="gradient"
Stroke="Black"
StrokeThickness="1"
Width="{Binding ActualWidth, ElementName=mainGrid}" Grid.ColumnSpan="3"
Visibility="Visible">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0" > >
<GradientStop Color="Green" Offset="0" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</Ellipse.Fill>
<Ellipse.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Mask}"
Stretch="None"
AlignmentX="Right"
AlignmentY="Top" />
</Ellipse.OpacityMask>
</Ellipse>
<Border Name="Mask2"
Grid.Column="0"
Background="White"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
</Border>
<Ellipse Name="BlueEllipse"
Fill="Blue"
Stroke="Black"
StrokeThickness="1"
Width="{Binding ActualWidth, ElementName=mainGrid}"
Grid.ColumnSpan="3" >
<Ellipse.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Mask2}"
Stretch="None"
AlignmentX="Left"
AlignmentY="Top"/>
</Ellipse.OpacityMask>
</Ellipse>
To achive what the original image is.

How to fill a Rectangle based on needs

I'm making a border with Rectangle on all sides. as the borders are so thin the user is not able to put the mouse on it. so I decided to fill with 2 colors so the user will see a small border and it will have more space to place the mouse. so the problem, when I'm filling the corners, I'm not able to fill the L shape. i need to fill topLeft rectangle in L please take a look at the image
Based on question
Why do you want to draw separate rectangles yourself?
as the window style will be none I'm writing a custom resizing I want which side I got the mouse. based on that writing resizing events.
The black boxes has to fill with yellow
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="1"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="1"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Grips -->
<!-- Sides -->
<Rectangle StrokeThickness="1" Grid.Column="1" Grid.Row="2" Name="bottom" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Color="White" Offset="0.5" />
<GradientStop Color="Yellow" Offset="0.5" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="0" Grid.Row="1" Name="left" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0">
<GradientStop Color="Yellow" Offset="0.5" />
<GradientStop Color="White" Offset="0.5" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="2" Grid.Row="1" Name="right" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0">
<GradientStop Color="White" Offset="0.5" />
<GradientStop Color="Yellow" Offset="0.5" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="0" Grid.Row="0" Name="topLeft" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" >
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="0" Grid.Row="2" Name="bottomLeft" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" />
<Rectangle StrokeThickness="1" Grid.Column="2" Grid.Row="2" Name="bottomRight" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" />
<Rectangle StrokeThickness="1" Grid.Row="0" Grid.Column="1" Name="top" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Color="Yellow" Offset="0.5" />
<GradientStop Color="White" Offset="0.5" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="2" Grid.Row="0" Name="topRight" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" />
<!--Content-->
</Grid>
Here are the 3 borders. how can I fill in that L shape thank you
New solution, try like this and compile to see if it works:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="5"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="5"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="5"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Grips -->
<!-- Sides -->
<Rectangle StrokeThickness="1" Grid.Column="1" Grid.Row="2" Name="bottom" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Color="White" Offset="0.5" />
<GradientStop Color="Yellow" Offset="0.5" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="0" Name="left" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" Width="1" Grid.RowSpan="2" HorizontalAlignment="Left" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0">
<GradientStop Color="Yellow" Offset="0.5" />
<GradientStop Color="Yellow" Offset="0.5" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="2" Grid.Row="1" Name="right" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0">
<GradientStop Color="White" Offset="0.5" />
<GradientStop Color="Yellow" Offset="0.5" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="0" Grid.Row="0" Name="topLeft" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" Fill="#02FFFFFF" Panel.ZIndex="1" />
<Rectangle StrokeThickness="1" Grid.Column="0" Grid.Row="2" Name="bottomLeft" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" />
<Rectangle StrokeThickness="1" Grid.Column="2" Grid.Row="2" Name="bottomRight" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" />
<Rectangle StrokeThickness="1" Grid.Row="0" Name="top" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" Fill="Yellow" Height="1" VerticalAlignment="Top" Grid.ColumnSpan="2" />
<Rectangle StrokeThickness="1" Grid.Column="2" Grid.Row="0" Name="topRight" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" />
<!--Content-->
</Grid>
You could add another grid into the corner instead of a rectangle (orange to see what changed):
<Grid Grid.Column="0" Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle StrokeThickness="1" Grid.Column="0" Grid.Row="0" Fill="OrangeRed"/>
<Rectangle StrokeThickness="1" Grid.Column="1" Grid.Row="0" Fill="OrangeRed"/>
<Rectangle StrokeThickness="1" Grid.Column="0" Grid.Row="1" Fill="OrangeRed"/>
</Grid>
If you want the corner mouse in that area, try this code instead.
The only change I made was setting the top corner to second column again, left corner to second row and filled your topLeftRectangle with the yellow color. Like this, that area can have different mouse:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="1"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="1"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Grips -->
<!-- Sides -->
<Rectangle StrokeThickness="1" Grid.Column="1" Grid.Row="2" Name="bottom" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Color="White" Offset="0.5" />
<GradientStop Color="Yellow" Offset="0.5" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="0" Grid.Row="1" Name="left" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0">
<GradientStop Color="Yellow" Offset="0.5" />
<GradientStop Color="Yellow" Offset="0.5" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="2" Grid.Row="1" Name="right" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0">
<GradientStop Color="White" Offset="0.5" />
<GradientStop Color="Yellow" Offset="0.5" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="0" Grid.Row="0" Name="topLeft" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" Fill="Yellow" >
</Rectangle>
<Rectangle StrokeThickness="1" Grid.Column="0" Grid.Row="2" Name="bottomLeft" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" />
<Rectangle StrokeThickness="1" Grid.Column="2" Grid.Row="2" Name="bottomRight" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" />
<Rectangle StrokeThickness="1" Grid.Row="0" Grid.Column="1" Name="top" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" Fill="Yellow" />
<Rectangle StrokeThickness="1" Grid.Column="2" Grid.Row="0" Name="topRight" MouseEnter="DisplayResizeCursor" MouseLeave="ResetCursor" PreviewMouseDown="Resize" />
<!--Content-->
</Grid>

how to change the color of the circle inside radio button

I want to change only the color inside the radio button when clicked. I mean the tiny dot inside the circle.
How in WPF can i do this?
I tried this code but it is saying the content is set more than once
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<StackPanel Orientation="Horizontal">
<Grid Width="40" Height="40">
<Ellipse Name="MainEllipse" Width="40" Height="40">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC8C8C8" Offset="0" />
<GradientStop Color="#FFF7F7F7" Offset="0.991" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Margin="10,10,10,10"
Fill="#C0C0C0"
Width="Auto"
Height="Auto" />
<Ellipse x:Name="Selected"
Margin="10,10,10,10"
Width="Auto"
Height="Auto">
<Ellipse.Fill>
<SolidColorBrush Color="Navy" />
</Ellipse.Fill>
</Ellipse>
</Grid>
<ContentPresenter Margin="5,0,0,0" VerticalAlignment="Center" />
</StackPanel>
</BulletDecorator.Bullet>
</BulletDecorator>
Thanks in advance,
John.
Move your ContentPresenter outside of your StackPanel. Actually, you don't appear to need the StackPanel at all:
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Grid Width="40" Height="40">
<Ellipse Name="MainEllipse" Width="40" Height="40">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC8C8C8" Offset="0" />
<GradientStop Color="#FFF7F7F7" Offset="0.991" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Margin="10,10,10,10"
Fill="#C0C0C0"
Width="Auto"
Height="Auto" />
<Ellipse x:Name="Selected"
Margin="10,10,10,10"
Width="Auto"
Height="Auto">
<Ellipse.Fill>
<SolidColorBrush Color="Navy" />
</Ellipse.Fill>
</Ellipse>
</Grid>
</BulletDecorator.Bullet>
<ContentPresenter Margin="5,0,0,0" VerticalAlignment="Center" />
</BulletDecorator>
This page might help you: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/35639a99-b2b2-4fe9-955d-775cb88ead43
It involves setting up a custom style for RadioButton.

WPF chessboard - how to draw in XAML

I need to draw a chessboard in WPF. I'm new in WPF and writing some working code in XAML is quite complicated for me.
So far I read that I should probably use a TileBrush however I don't really know how to use it. I also read that some people draw boards using UniformGrid, however I don't know how to fill in the grid's cells in the proper order. What is more I use canvas to do all my operations, so I don't know if I can use uniformgrid in canvas.
I also would like the board to resize if I change the dimensions of the window.
Is it possible to do that?
This done by code behind
http://www.c-sharpcorner.com/UploadFile/mahesh/391/
and if you want in XAML use UniformGrid
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
x:Class="WpfApplication9.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="600">
<Window.Resources>
<Color x:Key="BlackRes">Black</Color>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<UniformGrid Margin="29,29.5,23,32.5" Height="500">
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
<Rectangle Fill="White" Stroke="Black"/>
<Rectangle Stroke="Black">
<Rectangle.Fill>
<SolidColorBrush Color="{DynamicResource BlackRes}"/>
</Rectangle.Fill>
</Rectangle>
</UniformGrid>
</Grid>

How to draw a drop-shadow on a transparent rectangle?

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.

Resources