Corner-only borders in wpf/xaml - wpf

In some xaml, I'd like to have a border that is only out to a few pixels from each corner. So, along the top, the border would be, say, 5 pixels of black at the left edge, then be transparent across the rest of the top until 5 pixels of the right edge, and then the final 5 pixels of the border at the right edge would be black. The intent is to provide some guidance for selection of occasionally transparent things; however, in this application, the presence of a full border would interfere with the content (in the perceptual-visual sense). The corners are not rounded.
Something that looks like this:
-- --
| |
| |
-- --
What type of Brush should I use to achieve this effect?
I've tried a linear gradient, like so:
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Black" Offset="0" />
<GradientStop Color="Black" Offset="0.01" />
<GradientStop Color="Transparent" Offset="0.0101" />
<GradientStop Color="Transparent" Offset="0.9899" />
<GradientStop Color="Black" Offset="0.99" />
<GradientStop Color="Black" Offset="1" />
</LinearGradientBrush>
Of course, this only does the top left and bottom right. That could be reasonable for the intended application, but the size of the line on each corner is only the same if the region bordered is square (if the bordered area is a long rectangle, for instance, the section of border goes much further along one side than the other).
I did note the MappingMode value of "Absolute" on the gradient brushes. That works well for the top-left corner but not the other corners.
I also tried a RadialGradientBrush, thinking that I could get a ring to hit the corners, but wasn't successful in either centering it correctly or having it hit equal lengths along the sides.
This is part of the ItemContainerStyle in a ListBox, and the border is changed with a Trigger for IsSelected. For this reason, I also can't do borders within borders (within borders, etc.).
Edit #2: I also tried a VisualBrush. I knew I could get the behavior I wanted in a grid (at least, the stretching behavior).
<VisualBrush Stretch="Fill">
<VisualBrush.Visual>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" MaxWidth="10" MinWidth="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" MaxWidth="10" MinWidth="10" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10" MaxHeight="10" MinHeight="10" />
<RowDefinition Height="*" />
<RowDefinition Height="10" MaxHeight="10" MinHeight="10" />
</Grid.RowDefinitions>
<Rectangle Grid.Column="0" Grid.Row="0" Fill="Black" />
<Rectangle Grid.Column="1" Grid.Row="0" Fill="Transparent" />
<Rectangle Grid.Column="2" Grid.Row="0" Fill="Black" />
<Rectangle Grid.Column="0" Grid.Row="1" Fill="Transparent" />
<Rectangle Grid.Column="1" Grid.Row="1" Fill="Transparent" />
<Rectangle Grid.Column="2" Grid.Row="1" Fill="Transparent" />
<Rectangle Grid.Column="0" Grid.Row="2" Fill="Black" />
<Rectangle Grid.Column="1" Grid.Row="2" Fill="Transparent" />
<Rectangle Grid.Column="2" Grid.Row="2" Fill="Black" />
</Grid>
</VisualBrush.Visual>
</VisualBrush>
However, this doesn't work out, either. It seems like sizing doesn't happen in the same way inside a brush. In this case, the size of the Grid in the VisualBrush ended up being 20x20, with the middle transparent parts taking up no space. Setting HorizontalAlignment and VerticalAlignment to Stretch didn't help, either. Stretch="Fill" on the VisualBrush didn't do anything, either.
Edit #1: the wider context:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
</Style.Resources>
<Setter Property="Margin" Value="3" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderThickness" Value="5" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderBrush" Value="Fuchsia" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="4" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Black" Offset="0" />
<GradientStop Color="Black" Offset="0.01" />
<GradientStop Color="Transparent" Offset="0.0101" />
<GradientStop Color="Transparent" Offset="0.9899" />
<GradientStop Color="Black" Offset="0.99" />
<GradientStop Color="Black" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>

You could use Path ... this will draw something similar to what you're looking for:
<Path Stroke="Black" Stretch="Fill"
Data="M0,0 l10,0 m80,0 l10,0 m0,0 l0,10 m0,80 l0,10 m0,0 l-10,0 m-80,0 l-10,0 m0,0 l0,-10 m0,-80 l0,-10"
Height="100" Width="100" Margin="10" />
Full code sample:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Path Stroke="Black" Stretch="Fill"
Data="M0,0 l10,0 m80,0 l10,0 m0,0 l0,10 m0,80 l0,10 m0,0 l-10,0 m-80,0 l-10,0 m0,0 l0,-10 m0,-80 l0,-10"
Height="100" Width="100" Margin="10" />
</Grid>
</Window>

A radial gradient brush would probably achieve what you're looking for. Set the center of the radial brush to the center of your box. Start with a transparent center color, fade from the center to the desired "border color" (black), and then set the radius big enough that the black color only shows up in the corners.
And make sure to set the "gradient" to be very short - don't fade it gradually, but make it sharp.
If you size it right, you'll get an effect similar to that which is (poorly) illustrated below. The red box represents your content. Everything outside that box illustrates what your corners would look like. Make the radius of the "transparent" part bigger, to make your black corners smaller.
Finally; this would pretty much only look good with thin borders. If you have a thick border, it's going to look "funny" at the 'tips' of the corner brush.
Update:
Here's an actual example with some code:
<Border BorderThickness="1" Height="100" Width="100">
<Border.BorderBrush>
<RadialGradientBrush RadiusX="0.6" RadiusY="0.6">
<GradientStop Color="Black" Offset="1"/>
<GradientStop Color="#00000000" Offset="0.99"/>
</RadialGradientBrush>
</Border.BorderBrush>
<Rectangle Fill="Red" />
</Border>
And here's what it looks like:
For rectangular shapes (i.e. not a perfect square), in order to keep the corners the same size, you'd have to scale the RadiusX and RadiusY values accordingly. They should scale with the width/height ratio.

This is a fun question, so here's yet another possibility. I hope you agree that this qualifies as a fully separate answer from my previous one...
You can use a composite set of simple shapes - contained within a Grid - to achieve your desired effect. Layer your "content" box on top of 4 black rectangles, with each black rectangle positioned in the appropriate corner of the grid.
Here's my crappy paint illustration. Once again, the red box indicates your content. Anything outside of that red box is what the user will see as a border.
And the real-life example with code:
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Width="300" Height="200">
<!-- These rectangles will be the four corner "borders" -->
<Rectangle Fill="Black" Width="50" Height="50" HorizontalAlignment="Left" VerticalAlignment="Top" />
<Rectangle Fill="Black" Width="50" Height="50" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
<Rectangle Fill="Black" Width="50" Height="50" HorizontalAlignment="Right" VerticalAlignment="Top" />
<Rectangle Fill="Black" Width="50" Height="50" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
<!-- Here is the content. The "margin" property will effectively be the thickness of your corner borders. -->
<Rectangle Fill="Red" Margin="2" />
</Grid>
It looks like this:
This has the added benefit of scaling very well; the corner borders will always be the same size, no matter the size of your content. In addition, the border can be any thickness you like, without looking "weird" as the previous, radial-brush answer did.

Related

Can I make two containers (e.g. Grid and Canvas) take the same space to combine their abilities?

I have the following layout:
The Rectangles are placed using a Grid. On top of that, I want to add more "fluid" stuff, like Paths and lines that would be located dynamically.
For instance:
the lines between the Rectangles, are stretched from one Rectangle's mid-point to the mid-point of the one below it
The left-manually-drawn-ugly-red-"path" originate from the mid-point of the left-half of the top-Rectangle, and go to the mid-point of the left Rectange below it.
So the question is: the Rectangles match Grid behavior, other stuff, like the lines, match Canvas behavior. How do I use the advantages of both these containers? can I lay one over the other?
You don't need to mix and match your controls at all... you can chose either a Gird or a Canvas control to draw on using a Path element. Clearly, I don't want to do it all for you, so this is just a basic example of drawing in a Grid:
The end result:
The XAML:
<Grid Width="800">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Stroke" Value="Black" />
<Setter Property="Fill" Value="White" />
<Setter Property="StrokeThickness" Value="1" />
<Setter Property="Width" Value="250" />
<Setter Property="Height" Value="100" />
<Setter Property="Rectangle.RadiusX" Value="20" />
<Setter Property="Rectangle.RadiusY" Value="20" />
</Style>
</Grid.Resources>
<Path Grid.Row="1" Grid.RowSpan="2" Grid.Column="0" Data="M0,0 0,100" Stroke="Black" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" />
<Path Grid.Row="1" Grid.RowSpan="2" Grid.Column="1" Data="M0,0 0,100" Stroke="Black" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" />
<Rectangle Grid.Row="0" Grid.ColumnSpan="2" />
<Rectangle Grid.Row="1" Grid.Column="0" />
<Rectangle Grid.Row="1" Grid.Column="1" />
<Rectangle Grid.Row="2" Grid.Column="0" />
<Rectangle Grid.Row="2" Grid.Column="1" />
<Path Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="2" Data="M0,0 A 100,100 90 0 0 -100,100" Stroke="Red" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" Margin="0,0,150,0" />
<Path Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="2" Data="M0,0 A 100,100 90 0 1 100,100" Stroke="Red" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" Margin="0,0,-250,0" />
</Grid>
You can also find the syntax that you need to use in the Path.Data property in the Path Markup Syntax page on MSDN.
Yes you can lay the Canvas on top of a Grid, but you probably don't want to.
<Grid x:Name="container">
<!-- We use this to put the two items in the same location -->
<!-- i.e. Row="0" Column="0" is implicit for both the canvas and the grid below-->
<Grid x:Name="rectangleGrid"/>
<Canvas x:Name="shapeCanvas"/>
</Grid>
It really is that simple, but lets have a look at what we have now.
The shapeCanvas will be in front of the rectangleGrid (and if it isn't just tweak its ZIndex). If it has a non-transparent BackColor then you won't of course see the rectangleGrid, so you will need to sort that out.
If we want to line up the right hand red-line of yours we need to work out where to draw it from. Given that gridColumns don't expose sizes, then that's leftRectangle.ActualWidth + leftRectangle.Margin.Left + leftRectangle.Margin.Right + rightRectangle.Margin.Left + (rightRectangle.ActualWidth/2) and topRectangle.ActualHeight + topRectangle.Margin.Top + someConstantForHowTallThatSpacerRowIs + rightRectangle.Margin.Top + (rightRectangle.Height/2). Ouch
If we resize the container, then the rectangleGrid will also resize, but if you have used start-sizing for your columns then the rectangles all just resized. Now I have to go and recalculate all the sizes again.
So at this point, I'd start asking myself if I really wanted the rectangleGrid to handle the sizing or maybe I should just put everything into the Canvas.
You don't need to resize (although be careful because there are lots of high DPI screens out there now)
If you resize then the sizes are much simpler (e.g. if we assume that our margins are rectangles are 3/4 of the size and the margins 1/8 each side) so that redline top point now becomes shapeCanvas.Size *11/16 and (shapeCanvas.Height - someConstantForHowTallThatSpacerRowIs)/14

Progress bar showing Image, dot at some regular intervals

I need the progress bar which shows both the dot followed by icon after some regular intervals.
I am working on the camera module,when the snap is taken i need to show dot in the progress bar,which show the snap is taken.
Then this snap is passed to the algorthim and it retuns boolen value,then i need to show icon.
if the duration is 1 minutes and the interval is 30 sec ,then in the progress bar control i need to show two dot and two icon in the progress bar.
Please provide me some solutions,below is the XAMl
XAML For the Progress bar
<Window.Resources>
<Style x:Key="ProgressBarStyle" TargetType="ProgressBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border BorderBrush="#BBC6C4" BorderThickness="1" CornerRadius="5" Padding="1">
<Grid x:Name="PART_Track" >
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left" RadiusX="5" RadiusY="5">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF1D5666" Offset="1"/>
<GradientStop Color="#FF09B6FF"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Ellipse x:Name="progressdot" HorizontalAlignment="Left" Margin="73,7,0,0" Stroke="#FFA8A49B" Width="8" Height="8"
VerticalAlignment="Top" Grid.Row="1" />
<Image x:Name="imgAcetowhiteness" Margin="89,7,0,0" Source="..\acetowhiteness.png"
Stretch="Fill" Width="15" Height="15" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" />
<Ellipse x:Name="progressdot1" HorizontalAlignment="Left" Margin="180,7,0,0" Stroke="#FFA8A49B" Width="8" Height="8"
VerticalAlignment="Top" Grid.Row="1" />
<Image x:Name="imgAcetowhiteness1" Margin="195,7,0,0" Source="..\acetowhiteness.png"
Stretch="Fill" Width="15" Height="15" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel Orientation="Vertical">
<ProgressBar x:Name="PBarone" Margin="48,10,10,10" Style="{StaticResource ProgressBarStyle}"/>
<ProgressBar x:Name="PBartwo" Margin="48,20,10,10" Style="{StaticResource ProgressBarStyle}"/>
<ProgressBar x:Name="PBarthree" Margin="48,30,10,10" Style="{StaticResource ProgressBarStyle}"/>
</StackPanel>
</Grid>

Outer glow effect to border

How to provide the outer glow effect to border?
<Grid Width="200" Height="200">
<Grid.Background>
<RadialGradientBrush Center="0.5,0.5" GradientOrigin="0.5,0.5" RadiusX="0.8" RadiusY="0.8">
<RadialGradientBrush.GradientStops>
<GradientStop Offset="0" Color="#FF123B5F" />
<GradientStop Offset="1" Color="#FF001F31" />
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
</Grid.Background>
<Border Width="180" Height="180" Margin="10" Background="Transparent"
BorderBrush="White" BorderThickness="1">
<Border.BitmapEffect>
<OuterGlowBitmapEffect GlowColor="White" GlowSize="3" Opacity="1" />
</Border.BitmapEffect>
</Border>
</Grid>
I have tried this but it not working
BitmapEffects are no longer supported in .NET 4.0.
From MSDN
Important In the .NET Framework 4 or later, the BitmapEffect class is
obsolete. If you try to use the BitmapEffect class, you will get an
obsolete exception. The non-obsolete alternative to the BitmapEffect
class is the Effect class. In most situations, the Effect class is
significantly faster.
It isn't the same thing but you can try with a DropShadowEffect with ShadowDepth close to 0 instead.
Example
<Border Width="180" Height="180" Margin="10" Background="Transparent"
BorderBrush="White" BorderThickness="2" Opacity="1.0">
<Border.Effect>
<DropShadowEffect ShadowDepth="0"
Color="White"
Opacity="1"
BlurRadius="5"/>
</Border.Effect>
</Border>
Comparison between the BitmapEffects you had and DropShadowEffect above. DropShadowEffect to the right.

StackPanel with rounded and degraded background

Im trying to create a stackpanel with a rounded background, that also has a linearbrush from grey to trasparent
I used the ideas exposed here to prevent clipping
http://chriscavanagh.wordpress.com/2008/10/03/wpf-easy-rounded-corners-for-anything/
The problem now is that the text inside the stackpanel also has degradation and then turns invisible
any help?
Similar question
How do I create a WPF Rounded Corner container?
Code:
<Border Margin="235,78,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"
BorderBrush="Red" BorderThickness="1" CornerRadius="8" >
<Grid>
<Border Name="mask" CornerRadius="7">
<Border.Background>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<GradientStop Color="Gray" Offset="0"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<StackPanel Orientation="Horizontal" >
<StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=mask}"/>
</StackPanel.OpacityMask>
<Image Height="16" Width="16" RenderOptions.BitmapScalingMode="NearestNeighbor" />
<TextBlock Foreground="Black" Margin="5,0,3,0" Text="00620"/>
<TextBlock Foreground="Black" Margin="5,0,3,0" Text="Error sincronización" />
</StackPanel>
</Grid>
</Border>
This is due to the OpacityMask, try to remove these lines from your XAML:
<StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=mask}"/>
</StackPanel.OpacityMask>
And it should work

What is the best way to slide a panel in WPF?

I have a fairly simple UserControl that I have made (pardon my Xaml I am just learning WPF) and I want to slide the off the screen. To do so I am animating a translate transform (I also tried making the Panel the child of a canvas and animating the X position with the same results), but the panel moves very jerkily, even on a fairly fast new computer. What is the best way to slide in and out (preferably with KeySplines so that it moves with inertia) without getting the jerkyness. I only have 8 buttons on the panel, so I didn't think it would be too much of a problem.
Here is the Xaml I am using, it runs fine in Kaxaml, but it is very jerky and slow (as well as being jerkly and slow when run compiled in a WPF app).
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="1002" Height="578">
<UserControl.Resources>
<Style TargetType="Button">
<Setter Property="Control.Padding" Value="4"/>
<Setter Property="Control.Margin" Value="10"/>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Name="backgroundGrid" Width="210" Height="210" Background="#00FFFFFF">
<Grid.BitmapEffect>
<BitmapEffectGroup>
<DropShadowBitmapEffect x:Name="buttonDropShadow" ShadowDepth="2"/>
<OuterGlowBitmapEffect x:Name="buttonGlow" GlowColor="#A0FEDF00" GlowSize="0"/>
</BitmapEffectGroup>
</Grid.BitmapEffect>
<Border x:Name="background" Margin="1,1,1,1" CornerRadius="15">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0" Color="#FF0062B6"/>
<GradientStop Offset="1" Color="#FF0089FE"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
</Border>
<Border Margin="1,1,1,0" BorderBrush="#FF000000" BorderThickness="1.5" CornerRadius="15"/>
<ContentPresenter HorizontalAlignment="Center" Margin="{TemplateBinding Control.Padding}"
VerticalAlignment="Center" Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Canvas>
<Grid x:Name="Panel1" Height="578" Canvas.Left="0" Canvas.Top="0">
<Grid.RenderTransform>
<TransformGroup>
<TranslateTransform x:Name="panelTranslate" X="0" Y="0"/>
</TransformGroup>
</Grid.RenderTransform>
<Grid.RowDefinitions>
<RowDefinition Height="287"/>
<RowDefinition Height="287"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Panel1Col1"/>
<ColumnDefinition x:Name="Panel1Col2"/>
<ColumnDefinition x:Name="Panel1Col3"/>
<ColumnDefinition x:Name="Panel1Col4"/>
<!-- Set width to 0 to hide a column-->
</Grid.ColumnDefinitions>
<Button x:Name="Panel1Product1" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="Panel1Product1">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="00:00:00.6" Duration="0:0:3" From="0" Storyboard.TargetName="panelTranslate" Storyboard.TargetProperty="X" To="-1000"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
<Button x:Name="Panel1Product2" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button x:Name="Panel1Product3" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button x:Name="Panel1Product4" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button x:Name="Panel1Product5" Grid.Column="2" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button x:Name="Panel1Product6" Grid.Column="2" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button x:Name="Panel1Product7" Grid.Column="3" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button x:Name="Panel1Product8" Grid.Column="3" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Canvas>
</UserControl>
It looks like the best solution so far, is to use a Visual Brush and move two static images when sliding in and out the panels. Something similar to this is described in this blog post:
Using animated navigation pages in a WPF application (switched to web archive, but this is from 2008 so no promises if it is still the best technique).
I've found WPF performance of animations to improve significantly when not using BitmapEffects. Try disabling them in your example. I replaced my drop shadows with semi-transparent solid regions with gradient fills and performance improved.
I've also heard that some bitmap effects have increased performance in newer versions (maybe 3.5 SP1?) as more of the rendering has been pushed to the hardware.
If you work with WPF animations long enough, you'll figure out that large-area controls do, in fact, move in a what you call 'jerky' manner. I've had this problem even with tiny buttons that needed to move horizontally on the screen, and I have certainly given up on moving anything large (e.g., a window).

Resources