Nimble Coder

Adventures in Nimble Coding
posts - 79, comments - 68, trackbacks - 7

Friday, February 15, 2013

Using PowerShell to find changed SQL stored procedure parameters after DB product upgrade

I was upgrading a SQL based product that had been customized with wrappers around the product stored procedures. Once I realized that some of the stored procedures had new parameters, I needed to compare the differences and then identify the wrappers that used these stored procedures. The first step was to use INFORMATION_SCHEMA to list the parameters of all stored procedures. I ran the following query on the previous version and upgrade version of the database and saved the results

SELECT  p.SPECIFIC_NAME
    ,   p.PARAMETER_NAME
    ,   p.PARAMETER_MODE
    ,   p.CHARACTER_MAXIMUM_LENGTH
    ,   p.USER_DEFINED_TYPE_NAME
    ,   p.DATA_TYPE
    -- Do not include ORDINAL_POSITION for comparison
FROM    INFORMATION_SCHEMA.PARAMETERS p
ORDER BY p.SPECIFIC_NAME
    ,   p.ORDINAL_POSITION
2013-02-15 20_17_06-WinMerge - [MES35_DB_PARAMETERS.rpt - MES45_DB_PARAMETERS.rpt]With the saved report files, I used WinMerge to find the differences between the two databases.


At this point I realized I could use PowerShell to analyze the files and identify the changed stored procedures, and finally grep the directory with all of the saved stored procedures to find where the changes were used.

Here is the resulting PowerShell script:

$file1 = (Get-Content 'OLD_DB_PARAMETERS.rpt')
$file2 = (Get-Content 'NEW_DB_PARAMETERS.rpt')

# Compare the old and new stored procedure parameters
$diff = (Compare-Object $file1 $file2)

# Identify only the changes
$changedlines = ($diff | Where-Object {$_.SideIndicator -eq '=>'})

# Get the first field from the changed lines
$spnames = ($changedlines |% { $_.InputObject.split()[0] })
$spnames | Out-File "ChangedStoredProcedureNames.txt" -Encoding UTF8

# Use the directory where the source for the stored procedures is saved
$files = (Get-ChildItem 'C:\Database\StoredProcedures')

# Store the files containing the changed SPs. NOTE: This takes a while
# and is a brute force search that could probably be optimized signifcantly.
# The search uses the regex \b word boundary to search for the whole name.
$results = @()
$changednames |% {
    $pattern = $_
    $files |% {
        $file = $_.FullName
        $results += (Select-String -Pattern ("\b"+$pattern+"\b") -Path $file)
    }
}

# Save the results
$results | Out-File "FilesContainingChanges.txt" -Encoding UTF8

# You can also examine the results and group by the filename
$grouped = ($results | Group-Object -Property Filename)

posted @ Friday, February 15, 2013 10:05 PM | Feedback (0) | Filed Under [ SQL PowerShell ]

Tuesday, August 14, 2012

Configuring GPLEX in Visual Studio Solution

A long time ago I used a Lex-Yacc package for C++ called Parser Generator 2 but it was installed on a system that died many years ago. Recently I needed to modify that old project so I had to install it again. I was able to find the software and reinstall it and use my old validation code to get it working again. The process was painful though (rebuilding the libs for PG2 and VS2010 was not fun) and I wanted to convert the project to C#. I looked at PLY (Python Lex-Yacc) and I liked it, however I thought the transition might be quicker if I converted the project to C# first rather than Python. I came across Gardens Point Lex (GPLEX) and Parser Generator (GPPG) and they looked promising.

Initial Attempt

I decided to try a simple test using GPLEX that parsed the “GO” batch separators from SQL text. I started a test project in Visual Studio, created a Lex file (assume it was named “MyLexxer.lex”), and then added a Pre-build event command line to generate the C# lexxer. For simplicity, I added the “gplex.exe” binary executable to my source control under a “ExtRef” relative directory so the command was:

..\ExtRef\gplex.exe MyLexxer.lex

This generated “MyLexxer.cs”, however the disadvantage of this method was that it always re-generated the file every time regardless of whether the contents had changed.

Research

After searching the net, I found several possibilities but none of the references actually solved the issue of always re-compiling the Lex file. Here are the links I found:

  1. Understanding Custom Build Rules in Visual C++ 2005: Building Flex and Bison Files from the IDE – Concerned with C/C++ and not relevant to C# with Visual Studio 2008, 2010, etc.
  2. Using GPPG and GPLEX with Visual Studio – Not my exact issue, but it had a reference to link #3.
  3. Help Creating Default Managed Babel Project – This was the most useful link and I was able adapt this to my needs.

Using link #3, I modeled the syntax closer to what Visual Studio uses for XSD files that generate CS files and classes, but it wasn’t exactly the same. I opened the referenced “$(MSBuildBinPath)\Microsoft.CSharp.targets” file which was located in, “C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.targets” to help figure out the remaining items.

Solution

I had to manually edit my project file, but I managed to get the project to only compile the Lex file when it changed. Here are the steps:

  1. Change the generated CS file to be dependent on the LEX file:
        <Compile Include="MyLexxer.cs">
          <AutoGen>True</AutoGen>
          <DependentUpon>MyLexxer.lex</DependentUpon>
        </Compile>
  2. Add a separate ItemGroup section that includes the Lex build rule. I’m not sure if this really needs to be in a separate ItemGroup, but I did it anyway.
      <ItemGroup>
        <Lex Include="MyLexxer.lex" />
      </ItemGroup>
  3. Add the Lex build rule to the project file. I found I needed the %(RelativeDir) after another test with the Lex files in a separate directory. Note: You will need to alter the “Exec Command” for the path and parameters as necessary.
      <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
      <!-- I added the following build rules after the existing Import element -->
      <PropertyGroup>
        <BuildDependsOn>LexGenerator;$(BuildDependsOn)</BuildDependsOn>
        <CompileDependsOn>LexGenerator;$(CompileDependsOn)</CompileDependsOn>
      </PropertyGroup>
      <Target Name="LexGenerator" Inputs="@(Lex)" Outputs="@(Lex->'%(RelativeDir)%(Filename).cs')">
        <Exec Command="..\ExtRef\gplex.exe /stack /out:@(Lex ->'%(RelativeDir)%(Filename).cs') %(Lex.Identity)" />
        <CreateItem Include="%(Lex.RelativeDir)%(Lex.Filename).cs">
          <Output TaskParameter="Include" ItemName="FileWrites" />
        </CreateItem>
      </Target>
  4. Optional/unsure: Set the UseHostCompilerIfAvailable in the first PropertyGroup section. 
      <PropertyGroup>
        <UseHostCompilerIfAvailable>False</UseHostCompilerIfAvailable>
      </PropertyGroup>

posted @ Tuesday, August 14, 2012 2:15 PM | Feedback (0) | Filed Under [ C# Programming ]

Friday, December 09, 2011

Using PowerShell to Select a Unique Array

I had an XML file with names that I needed to verify in a database table, so I thought this would be a perfect task for PowerShell. The actual format of the XML file looked like this:

<menu>
  <id>symbol:U_F80_T410.ADDITIONS</id>
  <name>ADDITIONS</name>
  <click>True</click>
  <en>True</en>
</menu>

Obtaining the XML nodes was simple with PowerShell. I need to find the symbol name, so I selected the <menu> nodes that had <id> nodes starting with 'symbol:' and extracted the name with Substring():

$menuSymbols = $xml.SelectNodes("//menu[contains(id, 'symbol:')]") | % { $_.id.Substring(7) }

Next I need the tag name of each symbol (U_F80_T410 in the sample above). Some symbols don’t have tag names, and tag names can have multiple symbol names, e.g. U_F80_T410.ADDITIONS and U_F80_T410.OVERVIEW.

Method 1: Declare array first, then use the | % ForEach-Object alias

$menuTagNames = @() 
$menuSymbols | % { 
    $index = $_.IndexOf('.') 
    if ($index -gt 0) { 
        $tagName = $_.Substring(0, $index) 
        if ($menuTagNames -notcontains $tagName) { 
            $menuTagNames += $tagName 
        } 
    } 
} 

I thought there must be a more concise means to get the unique symbol names. A quick look at stackoverflow showed 'select -uniq' and 'sort -uniq' as methods to remove duplicates in PowerShell.

Method 2: Using Sort -Unique

$menuTagNames = $menuSymbols | % {
  $index = $_.IndexOf('.')
  if ($index -gt 0) { $_.Substring(0, $index) }
} | Sort -Unique 

It should be noted that Method 2 does not always return an array, but instead it depends how many items are returned from the pipeline. If no items are returned, the result will be $null. If one item is returned, the result will be a string since the underlying data type is string. If two or more items are returned, the result will be an array.

One other point to mention is that the underlying .NET data type for the PowerShell [array] is System.Array which is not optimized for large results or for searching for items in the list. I haven’t tested the performance aspects in this scenario, but the [hashtable] should theoretically be more efficient however it requires more memory and more code. I started to convert Method 2 into a hashtable:

Method 3: Method 2 using a hashtable

$menuTagNames = @{}
$menuTagNames = $menuSymbols | % {
    if ($_.IndexOf('.') -gt 0) {
        $_.Substring(0, $_.IndexOf('.'))
    }
} | Sort -Uniq | % $h.Add($_, $_)

I like Method 3, however it could be optimized further because the items in the 'if' conditional could be tested for duplicates immediately using the hashtable ContainsKey() method:

Method 4: Back to Method 1 except with a hashtable

$menuTagNames = @{} 
$menuSymbols | % { 
    $index = $_.IndexOf('.') 
    if ($index -gt 0) { 
        $tagName = $_.Substring(0, $index) 
        if ( !$menuTagNames.ContainsKey($tagName) ) { 
            $menuTagNames.Add($tagName, $tagName) 
        } 
    } 
} 

The more I play with PowerShell, the more I like it.

posted @ Friday, December 09, 2011 3:08 PM | Feedback (0) | Filed Under [ PowerShell ]

Thursday, January 21, 2010

Using Mercurial with Virtual Machines

Recently I have started using Mercurial (also known as ‘hg’ which is the command line tool) for source control management (also known as version control system) for some of my projects. Most of the projects I deal with use Subversion which is sufficient for most needs. My first exposure to distributed source control management was Linus Torvald’s presentation on git at Google. In a nutshell, he rails on CVS (his initial intention was to design a system as “What Would CVS Never Do” [WWCCVSND] and he considers tarballs and patches as superior to CVS) and also sees Subversion as “the most pointless project ever started.”

Popular Open Source Distributed SCMs / DVCSs

There are several popular open source distributed SCMs/DVCSs include Darcs, Bazaar, Mercurial, and Git. Currently, it seems that Git is the most “popular” of the bunch (at least in the blogs and tweets that I’ve seen) due to the github and projects like the Linux kernel and others. A quick comparison from stackoverflow also verifies popularity in terms of the number of tags related to the respective systems (I listed the main tag only although there were quite a few subtags for Git and Mercurial):

stackoverflow-scm-popularity

Why Mercurial?

I believe Mercurial, Git, and other DVCSs will work great for most cases. There are several analyses on the web with varying results, but the all of the available open source DVCSs are strengths and weaknesses and are capable. That being said, there are several reasons why Mercurial is a good choice.

1. Portability

Mercurial is written primarily in Python with small portions written in C for speed. This makes it extremely portable to almost every architecture. While Git is available on POSIX systems, there are basically two Windows versions with one requiring Cygwin and the other is called msysGit.

2. TortoiseHG

Another reason is TortoiseHg which is a shell extension primarily for Windows, although there is a Gnome/Nautilus CLI extension and a Mac OS X version is in the works. TortoiseHg is written with gtk/tkinter so that makes it easier to port to other systems than TortoiseSVN or TortoiseGit (both are Windows only) although I wish TortoiseHg used wxPython instead. I’ve also used QGit and GitGUI the experience with Tortoise* is generally better in my opinion.

3. “Smart” HTTP

Mercurial has built-in “smart” HTTP which leads to more efficient transfer when using HTTP. There is discussion of Git implementing smart HTTP. The reason HTTP is important is it is a universal common denominator. Some corporations block the ports used for native git or git+ssh access. Also, I have done work with people in foreign countries where the native protocols didn’t work, or we could use ssh, and HTTP was the only option.

'hg serve' is an extremely easy way to start the Mercurial internal web server. As one person noted:

I chose Mercurial since it feels clean and elegant -- I was put off by the shell/Perl/Ruby scripts I got with Git. Try taking a peek at the git-instaweb.sh file if you want to know what I mean: it is a shell script which generates a Ruby script, which I think runs a webserver. The shell script generates another shell script to launch the first Ruby script. There is also a bit of Perl, for good measure.

4. Google support

Google officially supported Mercurial for project hosting in Google Code on Friday, April 24, 2009. Google also released a report on their internal DVCS analysis with the following summary:

Summary

In terms of implementation effort, Mercurial has a clear advantage due to its efficient HTTP transport protocol.

In terms of features, Git is more powerful, but this tends to be offset by it being more complicated to use.

I personally doubt Google’s support of Mercurial will sway the DVCS competition significantly towards Mercurial as I believe Git is powerful, robust, and here-to-stay. Google’s support does give significant credence to Mercurial though. I expect improvement in both Git and Mercurial in the future which will probably blur the lines even more.

Using Mercurial with VMs

virtual-machine-network-setting-host-only The primary benefit of using a DVCS with virtual machines is that the VM does not need to be connected to the outside world but instead only needs access to the host. Most of my VMs use “Host only” networking which allows the VM to connect to the host, but not the outside network or Internet. Thanks to the easy Mercurial built-in web server, it is easy to share a repository from the host to the VM.

Step 1: Create or Clone repository on Host

For example, if we take the 'hello' repository from the Mercurial tutorial, we can clone an existing repository on the host environment:

tortoisehg-clone-my-hello

Step 2: Starting the Mercurial Web Server

You can either start the web server by using 'hg serve' from the repository directory, or use TortoiseHg Web Server:

tortoisehg-context-menu-web-server tortoisehg-serve-my-hello

If you are going to be pushing repository changes from the VM back using HTTP, then don’t forget to enable pushing via HTTP in the host '$(repository)/.hg/hgrc' file:

[web]
allow_push = *
push_ssl = false

Step 3: Cloning the Repository from the VM

This step is similar to Step 1, except change the source to the repository on the host, e.g. :8000/">http://<yourmachinename>:8000/.

Then modify the source as necessary on the VM and commit your changes to the local repository.

Step 4 – Option A: Pushing Changes back to the Host

Once you are ready, you can push your changes back to the repository on the host:

tortoisehg-repoexplore-my-hellotortoisehg-push-success

If you get a failure, then check the [web] settings in Step 2 and restart the web server if you change the 'hgrc' file.

Step 4 – Option B: Pulling the Changes back to the Host

Alternatively, you could start the Mercurial Web Server on the VM and pull the changes from the host. This just requires you to start the web server on the VM, and also make sure the specified port, e.g. 8000, is not used by another web server and is open. You can add a sync alias for the VM(s) which makes it easy to switch to different sources/repositories with the Repository Explorer:

tortoisehg-settings-sync tortoisehg-repoexplore-vm-my-hello

Conclusion

It is easy to use Mercurial, or Git for that matter, in combination with development on virtual machines to allow developers to commit and experience a real SCM/VCS experience.

posted @ Thursday, January 21, 2010 3:31 PM | Feedback (1) | Filed Under [ Mercurial ]

Wednesday, December 30, 2009

Animated Clocks for SVG and Silverlight

At one point in time I found a cool clock graphic and I was looking for it again because it gave a fairly detailed explanation on making a nice looking vector based clock (it was the Codeproject article by Marc Clifton). During my search I found numerous implementations of both SVG and Silverlight clocks and I decided to catalog my findings.

The animated clocks are not necessarily practical to display on web pages, but an interesting exercise and fun as well.

SVG Clocks

Adobe SVG Clock

AdobeSvgClock by Adobe (unknown date)

A very basic looking clock that uses three <animateTransform type="rotate"> for the hour, minute, and second hands along with a load script to initialize the hands. Note that Adobe has discontinued their SVG Viewer and there are conflicts between SVG and Flash.

Experiments: SVG Clock

BurningBirdSvgClock by Shelley Powers on November 30, 2007

This is an improvement on a very simple SVG clock by Jason Davis (the original link was not working). This implementation supports displaying time in a different time zone rather than the user’s current time using the statement: setInterval("setClock(calcTime(-6))", 1000);. The code is licensed with LGPL.

I had to download the file directly as it was not shown in FF 3.5. The author has a rather appropriate statement in the article:

Is the clock worth the extra burden on the client's machine? Yes, and no. As a demonstration of what you can do with SVG and simple animation, I think it's a valuable tool. There is a Catch 22 about SVG: we don't use SVG because browser support is incomplete or inefficient; effort to better incorporate SVG is of secondary importance because SVG is little used. The only way to break this cycle is to actually start using the specification, and pushing a bit at the edges while we go about it.

Binary Clock

200px-Binary_clock_svg by Alexander Jones & Eric Pierce from Wikipedia on October 14, 2006

This is Wikipedia entry that I thought was animated but it turns out it is not animated. Bummer. It wouldn’t be hard to animate though. 

SVG + Javascript Analogue Clocks

SvgJavascriptAnalogueClock by Kam-Hung Soh

This example uses Javascript at the DOM document level rather than inside the SVG document to rotate the clock hands. It also uses a regular expression to change the rotation angle.

Animated SVG Clock Gears

AnimatedClockGears

by Tavmjong Bah (unknown date)

This is a really cool example created with Inkscape where every gear is independent and does not interfere with other gears. According to the author, the gears outlines were generated with a Python script by Aaron Spike.

Siemens Wall Clock

SiemensWallClockSvg by Stefan Oskamp (unknown date)

A nice looking clock that uses inline SVG along with a Javascript setInterval function to adjust the rotate attributes for the hour, minute, and second hands. The actual background is a 256 x 256 PNG file, rather than a vector based image.

An SVG Clock

SvgClockWithCountdown by Damien Dawber (ibuildstuff.net)

This clock is a self generated SVG image using JavaScript and the Raphael JavaScript Vector Library.

SVG Clock Gallery

SimpleAnalogClock

by G. Wade Johnson

A clock with a sunburst effect that uses an external script to drive the animation. The author also has a version that runs backwards by simply changing a parameter in the initialization script.

24-Hour '12'-at-the-top Analog Clock

24h_clock_v2.2

by Steve Pomery

A nice looking clock created using Inkscape. Now at version 2.2. 

SVG Resurgent

SvgResurgentClock by Chris W. Johnson on April 29, 2008

An inline base64 encoded SVG clock. The SVG has a version of the Google analytics tracking script "because it's nice to know if people care."

Silverlight Clocks

Microsoft Silverlight Clock Samples

Silverlight1ClockSample by Microsoft

A clock sample from the Silverlight 1.0 SDK which uses clock.xaml and clock.js to create the clock. The result is actually very similar to some of the SVG implementations since Silverlight 1.0 did not have codebehind capability.

Version 2.0 of the clock uses codebehind along with a XAP file. There is also a version using IronRuby although the XAP file is significantly larger (11KB vs 1MB!) because it includes several assemblies in the XAP. Then there is the Python version as well which is almost identical to the Ruby version except for the language substitution.

There is also a Microsoft walk-through: Creating a Silverlight Clock by Using Expression Blend or Code, which has a detailed step by step guide for Expression Blend.

A Vector Graphics Rendered Animated Clock

VectorGraphicsRenderedClock by Marc Clifton on April 18, 2004

A very nice looking clock complete with a walkthrough on how to create the look and feel of the clock. Technically this isn’t a Silverlight clock as it is intended for the (now defunct) MyXaml and then improved upon by VG.net. The graphics should be mostly compatible with Silverlight though I haven’t tested it yet.

Developing Silverlight Analog Clock – pattern oriented approach

SilverlightClockPatternOriented SilverlightClockPatternOriented2 by Pencho Popadiyn on October 30, 2008

Version 1 introduces the MVP design pattern and the design of the clock using the MVP pattern.

Version 2 - This implementation uses VS2008, .NET 3.5, Silverlight 2 using an MVP pattern. The sample has a very nice looking graphic and improves upon the Clock view.

Hybrid Clock in Silverlight 2

HybridClock by Alex Bell on November 7, 2008 (based on SVN timestamps)

A modest clock using Silverlight although the author claims:

Hybrid Clock is, by far, the most sophisticated animated Date/Time visualization control developed for Microsoft Silverlight™ 2.0.

Beauty with Silverlight: Ball Watch Animation

BallWatchSilverlightby Michael S. Scherotter on April 24, 2008

This is a gorgeous clock using Silverlight, Expression Blend, and Expression Design. For some reason this is a Silverlight 1.0 applet instead of 2.0 which means it uses some Javascript event triggering for the loading, but it looks great.

Miscellaneous Silverlight Clocks

I was taking way too much time, so here are other implementations without screen shots.

http://www.c-sharpcorner.com/UploadFile/nipuntomar/SilverlightClock08122008132436PM/SilverlightClock.aspx – A good Silverlight clock.

http://pixelplastic.de/2008/01/12/ZoomableUltraHighResolutionSilverlightClock.aspx – A Silverlight clock that allows the user to drag and move the clock. The applet did not work in IE or FF, so I assume it was developed with a pre-release version and has not been updated on the blog article. You can download the source code though. Marcel Hoyer has an older version of the clock as well as other cool Silverlight examples on his blog.

http://weblogs.asp.net/andrewrea/archive/2009/08/12/programmatic-drawing-with-silverlight-2-0-3-0-an-analogue-clock.aspx – A basic looking clock although the clock is mostly generated by code (tick marks, etc.) which is cool. The blog post has a lengthy code listing and downloadable code.

WPF Clocks

Another Xamlifferous Experience (an All-XAML Clock)

AllXamlClock by Charles Petzold on April 7, 2006

This is an all XAML clock without any C# or .NET code. It was based on a Microsoft sample and Charles Petzold improved upon that sample by eliminating the C# code, improved the animation technique, and eliminated the repetition in the XAML. The clock graphic is basic and not fancy, but practical.

posted @ Wednesday, December 30, 2009 1:17 AM | Feedback (8) | Filed Under [ SVG Programming SilverLight ]

Friday, January 30, 2009

Using a delegate and Custom Appender with log4net to display live log text

log4netAppender sample Recently I needed to display the text that was sent to log4net in a TextBox in a Form. It turns out this is very easy to do using a custom appender and the AppenderSkeleton. The custom appender uses a delegate to allow the host program to define a callback function to handle the log text as necessary.

1. Create a new custom appender class

I named my appender DelegateAppender because it needed to use a delegate to pass the text to the Form.

using log4net.Core;

namespace log4net.Appender
{
    public delegate void LogTextAppend(string text);

    public class DelegateAppender : log4net.Appender.AppenderSkeleton
    {
        private LogTextAppend logTextAppend;

        public LogTextAppend LogTextMethod
        {
            get { return logTextAppend; }
            set { logTextAppend = value; }
        }

        public DelegateAppender()
        {
            logTextAppend = EmptyAppend;
        }

        private void EmptyAppend(string text)
        {
            // Do nothing
        }

        protected override void Append(LoggingEvent loggingEvent)
        {
            if (logTextAppend != null)
                logTextAppend(RenderLoggingEvent(loggingEvent));
        }
    }
}

2. Create and assign the delegate to the appender

As far as I could tell, there was no easy way to specify the delegate to use in the configuration of the DelegateAppender. Therefore I added a simple method to assign the delegate in the Form to the DelegateAppender.

public void AddStatus(string message)
{
    textBoxStatus.AppendText(message);
}

private void InitializeLogging()
{
    bool initialized = false;

    if (!log.Logger.Repository.Configured)
    {
        log4net.Config.XmlConfigurator.Configure();
        textBoxStatus.AppendText("WARNING: log4net not automatically configured. " +
            "Check AssemblyInfo.cs for - " +
            "[assembly: log4net.Config.XmlConfigurator(Watch=true)]\r\n");
    }

    foreach (log4net.Appender.IAppender appender in log.Logger.Repository.GetAppenders())
    {
        if (appender.GetType() == typeof(log4net.Appender.DelegateAppender))
        {
            log4net.Appender.DelegateAppender delegateAppender = (log4net.Appender.DelegateAppender) appender;
            // .NET 2.0+
            delegateAppender.LogTextMethod = this.AddStatus;
            // .NET 1.1
            //delegateAppender.LogTextMethod = new log4net.Appender.LogTextAppend(this.AddStatus);
            initialized = true;
        }
    }

    if (!initialized)
    {
        textBoxStatus.AppendText("ERROR: Unable to add DelegateAppender to logging!\r\n");
    }
}

3. Add the log4net configuration to app.config and AssemblyInfo.cs

The code for AssemblyInfo.cs just tells log4net to configure itself and also watch for changes.

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

The app.config is as follows: 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <configSections>
  <section
   name="log4net"
   type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"
  />
 </configSections>

 <log4net>
  <logger name="log4netAppender.LogTestForm">
   <level value="ALL"/>
  </logger>
  <root>
   <level value="ALL" />
   <appender-ref ref="DelegateAppender" />
  </root>
  <appender
    name="DelegateAppender"
    type="log4net.Appender.DelegateAppender" >
   <layout type="log4net.Layout.PatternLayout">
    <param
     name="ConversionPattern"
     value="%m%n"
    />
   </layout>
  </appender>
 </log4net>
</configuration>

And there is a simple example of how to create a custom appender with log4net and hook it into an application.

Technorati tags: ,

posted @ Friday, January 30, 2009 12:42 PM | Feedback (5) | Filed Under [ C# ]

Thursday, November 06, 2008

Spinning Wait Symbol in Silverlight, Part4

SpinningCursor4-TestPage

Series History

 

Introduction

The goal of these posts is to build a spinning cursor similar to the Mac OS X wait cursor through programmatic means in Silverlight. The cursor is still very rough and will undergo improvements progrressively. One of the reasons to build the cursor programmatically is to have more control over the output such as changing the number of slices or rotation or other parameters.

For this post, I added an animation to the rotation angle of the canvas which causes the slices to spin. I also added a simple navigation to the previous examples.

Step 1: Adding the Animation

In the previous post, I had one canvas for the background image as well as the slices. This time I realized I needed two canvases: one for the background and one for the slices. I needed separate canvases so that I could apply a rotation transform animation to the slices without affecting the background image. I used Expression Blend 2.0 sp1 and selected the "SpinningCanvas" and added an Storyboard named "SpinStoryboard". I then changed the Angle of the RotateTransform from 0 - 360° for the time range 0.0 - 2.0 sec.

SpinningCursor4-BlendAnimation

This resulted in the following XAML:

<UserControl.Resources>
    <Storyboard x:Name="SpinStoryboard" RepeatBehavior="Forever">
        <DoubleAnimationUsingKeyFrames
            BeginTime="00:00:00"
            Storyboard.TargetName="SpinningCanvas"
            Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
            <SplineDoubleKeyFrame KeyTime="00:00:02" Value="360"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</UserControl.Resources>

Step 2: Starting the Animation

When the control is created or updated, the Update() method is called. I modified the method as follows:

void Update()
{
    SpinStoryboard.Stop();
    CursorCanvas.Children.Clear();
    SpinningCanvas.Children.Clear();
    CreateOutlineGuides(CursorCanvas);
    CreateBackground(CursorCanvas);
    CreateSlicePaths(SpinningCanvas);
    SpinStoryboard.Begin();
}

Step 3: Adding the Sample Navigation

I wanted to support future samples, so I used reflection to find all of the UserControls not including App or Page. I used a Dictionary<string, Type> to map the Type.Name with the Type in case I need it for future samples. I then dynamically created a button for each sample.

void Page_Loaded(object sender, RoutedEventArgs e)
{
    Assembly assembly = Assembly.GetExecutingAssembly();
    Type[] exportedTypes = assembly.GetExportedTypes();
    foreach (Type t in exportedTypes)
    {
        // Testing various inheritance detection methods
        bool isNotApp = (t != typeof(App));
        bool isNotSelf = (t != this.GetType());
        bool isUserControl = t.IsSubclassOf(typeof(UserControl));

        if (isNotApp && isNotSelf && isUserControl)
        {
            _implementedTypes.Add(t.Name, t);
        }
    }

    Button lastButton = null;

    // Sort the names of the UserControls to make more sense
    List<string> sortedKeys = new List<string>(_implementedTypes.Keys);
    sortedKeys.Sort();

    for (int index = 0; index < _implementedTypes.Count; ++index)
    {
        string key = sortedKeys[index];
        Type t = _implementedTypes[key];
        lastButton = AddButton(t, index);
    }

    // Use the last UserControl for the initial display
    if (lastButton != null)
    {
        Button_Click(lastButton, null);
    }
}

To make it simple, I used name of the UserControl for the Button.Content and in the Button_Click event I used System.Activator to create an instance of the class.

private void Button_Click(object sender, RoutedEventArgs e)
{
    UIElement control = null;

    try
    {
        Button button = sender as Button;
        string typeName = button.Content as string;
        Type type = _implementedTypes[typeName];
        object instance = System.Activator.CreateInstance(type);
        control = instance as UIElement;
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.ToString());
    }

    WorkArea.Children.Clear();
    if (control != null)
        WorkArea.Children.Add(control);
}

Conclusion

The animation looks nice and adds a lot to the overall effect. For the next part, I plan to dynamically create the animation instead of using Blend and perhaps improve the background shape to more closely resemble the Mac OS X spinning cursor.

kick it on DotNetKicks.com
Technorati tags: ,

posted @ Thursday, November 06, 2008 2:03 AM | Feedback (4) | Filed Under [ C# SilverLight ]

Wednesday, October 29, 2008

Spinning Wait Symbol in Silverlight, Part3

SpinningCursor3-TestPage

Series History

In this post, I add curvature to the slices and refactor the code to support upcoming features. The goal of these posts is to build a spinning cursor similar to the Mac OS X wait cursor through programmatic means in Silverlight. One of the reasons to build the cursor programmatically is to create it will different number of slices or rotation or other parameters. At this point, the cursor is still very rough and just beginning to resemble the final result. In upcoming posts, I will animate the cursor and adjust the appearance to more closely resemble the desired cursor.

Step 1: Adjust the cursor properties

I added AlternateSlices and Origin properties, and also DefaultSliceCount and DefaultRotationAngle to the class.

public static readonly int DefaultSliceCount = 10;
public static readonly double DefaultSliceRotationAngle = 360.0 / DefaultSliceCount;

/// <summary>
/// Show alternating slices (true) or all slices (false)        
/// </summary> 
public bool AlternateSlices { get; set; }

/// <summary>        
/// The origin of the ellipse for the spinning cursor 
/// </summary> 
public Point Origin { get; private set; }

Step 2: Set the default parameter values

I specified the default slice count and the radius and origin of the cursor.

void Page_Loaded(object sender, RoutedEventArgs e)
{
    txtVersion.Text = this.GetType().Name;
    AlternateSlices = true;
    SliceCount = DefaultSliceCount;
    txtSliceCount.Text = Convert.ToString(SliceCount);

    SliceRotationAngle = DefaultSliceRotationAngle;
    txtRotation.Text = Convert.ToString(SliceRotationAngle);

    RadiusX = SpinningCanvas.Width / 2.0;
    RadiusY = SpinningCanvas.Height / 2.0;
    Origin = new Point(RadiusX, RadiusY);

    Update();
}

Step 3: Create a background circle (ellipse)

I used a simple linear gradient for now because the final gradient looks much more complicated and will take more time.

void CreateBackground(Canvas cursorCanvas)
{
    GradientBrush brush = new LinearGradientBrush();
    GradientStop stop1 = new GradientStop();
    stop1.Color = Color.FromArgb(255, 255, 0, 0);
    stop1.Offset = 0.25;
    brush.GradientStops.Add(stop1);

    GradientStop stop2 = new GradientStop();
    stop2.Color = Color.FromArgb(255, 0, 255, 0);
    stop2.Offset = 0.5; // cursorCanvas.Width / 2.0;
    brush.GradientStops.Add(stop2);

    GradientStop stop3 = new GradientStop();
    stop3.Color = Color.FromArgb(255, 0, 0, 255);
    stop3.Offset = 0.75; // cursorCanvas.Width;
    brush.GradientStops.Add(stop3);

    Ellipse ellipse = new Ellipse();
    ellipse.Height = cursorCanvas.Height;
    ellipse.Width = cursorCanvas.Width;
    ellipse.Fill = brush;
    cursorCanvas.Children.Add(ellipse);
}

Step 4: Implement the alternating slices

Implementing the alternating slices was simple:

/// <summary>
/// Create an ellipse using rotated slices to build the ellipse
/// </summary>
void CreateSlicePaths(Canvas cursorCanvas)
{
    // Create Slices
    for (int index = 0; index < SliceCount; ++index)
    {
        PathFigure pathFigure = CreateSliceFigure();

        PathGeometry pathGeometry = new PathGeometry();
        pathGeometry.Figures.Add(pathFigure);

        Path path = new Path();
        path.Stroke = new SolidColorBrush(Color.FromArgb(128, 0, 0, 0));
        path.StrokeThickness = 1.0;
        path.Fill = new SolidColorBrush(Color.FromArgb(192, 128, 128, 128));
        path.Data = pathGeometry;

        // Rotate the slice for all slices after the first slice
        if (index > 0)
        {
            RotateTransform t1 = new RotateTransform();
            t1.CenterX = RadiusX;
            t1.CenterY = RadiusY;
            t1.Angle = SliceCenterAngle * index;

            TransformGroup transformGroup = new TransformGroup();
            transformGroup.Children.Add(t1);
            path.RenderTransform = transformGroup;
        }

        cursorCanvas.Children.Add(path);

        if (AlternateSlices)
            ++index;
    }
}

Step 5: Add the curvature to the slices

The curvature isn't perfect, but it looks fine with the default settings (10 slices and 36° rotation). I used a Bezier curve, but perhaps the standard arc would work better in the future.

// Curve control weighting
double curveWeight = 0.75;

// Create the first line
BezierSegment seg1 = new BezierSegment();
seg1.Point1 = point0;
seg1.Point2 = CalculatePointOnEllipse(0.0, RadiusX * curveWeight, RadiusY * curveWeight, Origin);
seg1.Point3 = point1;
pathFigure.Segments.Add(seg1);

// Use an arc for the circular side
ArcSegment seg2 = new ArcSegment();
seg2.Point = point2;
seg2.Size = new Size(RadiusX, RadiusY);
seg2.RotationAngle = SliceCenterAngle;
seg2.IsLargeArc = (SliceCenterAngle > 180.0);
seg2.SweepDirection = SweepDirection.Counterclockwise;
pathFigure.Segments.Add(seg2);

// Close shape by going back to the starting point
BezierSegment seg3 = new BezierSegment();
seg3.Point1 = point2;
seg3.Point2 = CalculatePointOnEllipse(SliceCenterAngle, RadiusX * curveWeight, RadiusY * curveWeight, Origin);
seg3.Point3 = point0;
pathFigure.Segments.Add(seg3);

Conclusion

The spinning cursor now has a dynamic number of slices and rotation angle, and it is starting to look more like the desired result. In the next post, I will animate the cursor to give it the spinning effect.

Technorati tags: ,
kick it on DotNetKicks.com

posted @ Wednesday, October 29, 2008 11:16 AM | Feedback (4) | Filed Under [ C# SilverLight ]

Monday, October 20, 2008

Spinning Wait Symbol in Silverlight, Part 2

After my previous spinning wait symbol, I decided to see how difficult it would be to create a Silverlight version of the Mac OSX wait cursor that I referenced in the previous post. The Mac OSX cursor is commonly referred to as the "Spinning Pizza of Death" or the "Marble of Doom" and in fact there is a Marble of Doom web site dedicated to the amount of time spent waiting while watching the spinning cursor. The Marble of Doom web site has a very nice and large version of the cursor using Flash although it doesn't have any vector information but is using video frames (they probably just published the final product and did not include the vector/animation information). The purpose of this post is to programmatically build the cursor and then in later posts to animate it.

Step 1: Decide on the initial interface properties

I realized quickly that I would need a little geometry to programmatically build the cursor, but the first step was to build the interface requirements. The essential properties were:

public int SliceCount { get; set; }
public double SliceCenterAngle { get; private set; }
public double SliceRotationAngle { get; set; }
public double RadiusX { get; set; }
public double RadiusY { get; set; }

The SliceCount determines how many slices or divisions to create, and the SliceCenterAngle is simply 360° / SliceCount. The SliceRotationAngle is the angle to twist or bend the slice. I decided to have a RadiusX and RadiusY to support ellipses in the future as well.

Step 2: Manually create a slice

Manual slice in Blend Before I could programmatically create a slice, I needed to find out how to create a slice using XAML and Blend. The points on the slice would be in the center of the circle, and then two points on the circle determined by the SliceCenterAngle. The biggest question was how to create the arc and maintain the circular appearance. Fortunately, the Geometry Overview on MSDN was very helpful and got me started on the right track with the PathGeometry. I was able to create the simplest scenario with a single slice from a circle with four slices:

<Path Stroke="Black" StrokeThickness="1">
    <Path.Data>
        <PathGeometry>
            <PathGeometry.Figures>
                <PathFigure StartPoint="50,50">
                    <PathFigure.Segments>
                        <LineSegment Point="0,50" />
                        <ArcSegment Size="50,50" IsLargeArc="False"
                            RotationAngle="90" SweepDirection="CounterClockwise" Point="50,100" />
                        <LineSegment Point="50,50" />
                    </PathFigure.Segments>
                </PathFigure>
            </PathGeometry.Figures>
        </PathGeometry>
    </Path.Data>
</Path>

The next step was to create the same quarter-circle except with two slices:

<Path Stroke="Black" StrokeThickness="1">
    <Path.Data>
        <PathGeometry>
            <PathGeometry.Figures>
                <PathFigure StartPoint="50,50">
                    <PathFigure.Segments>
                        <LineSegment Point="0,50" />
                        <ArcSegment
                            Size="50,50"
                            Point="14.645,85.355" 
                            RotationAngle="45" 
                            IsLargeArc="False"
                            SweepDirection="CounterClockwise" 
                        />
                        <LineSegment Point="50,50" />
                    </PathFigure.Segments>
                </PathFigure>
                
                <PathFigure StartPoint="50,50">
                    <PathFigure.Segments>
                        <LineSegment Point="14.645,85.355" />
                        <ArcSegment
                            Size="50,50"
                            Point="50, 100" 
                            RotationAngle="45" 
                            IsLargeArc="False"
                            SweepDirection="CounterClockwise" 
                        />
                        <LineSegment Point="50,50" />
                    </PathFigure.Segments>
                </PathFigure>
            </PathGeometry.Figures>
        </PathGeometry>
    </Path.Data>
</Path>

Step 3: Create a slice programmatically

The general idea is to create one slice and then rotate the slice around the circle to create the complete circle.

/// <summary>
/// Create an ellipse using rotated slices to build the ellipse
/// </summary>
void CreateSlicePaths(Canvas cursorCanvas)
{
    SliceCenterAngle = 360.0 / SliceCount;

    // Create Slices
    for (int index = 0; index < SliceCount; ++index)
    {
        PathFigure pathFigure = CreateSliceFigure();

        PathGeometry pathGeometry = new PathGeometry();
        pathGeometry.Figures.Add(pathFigure);

        Path path = new Path();
        path.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
        path.StrokeThickness = 1.0;
        path.Data = pathGeometry;

        // Rotate the slice for all slices after the first slice
        if (index > 0)
        {
            RotateTransform t1 = new RotateTransform();
            t1.CenterX = RadiusX;
            t1.CenterY = RadiusY;
            t1.Angle = SliceCenterAngle * index;

            TransformGroup transformGroup = new TransformGroup();
            transformGroup.Children.Add(t1);
            path.RenderTransform = transformGroup;
        }

        cursorCanvas.Children.Add(path);
    }
}

/// <summary>
/// Create the base shape for the slice
/// </summary>
private PathFigure CreateSliceFigure()
{
    // Start at the center of the ellipse
    Point point0 = new Point(RadiusX, RadiusY);

    // Next point is the left side of the ellipse
    //Point point1 = new Point(0.0, RadiusY); // if no rotation
    Point point1 = CalculatePointOnEllipse(SliceRotationAngle);

    // Calculate the bottom point on the ellipse
    Point point2 = CalculatePointOnEllipse(SliceRotationAngle + SliceCenterAngle);

    // Starting point
    PathFigure pathFigure = new PathFigure();
    pathFigure.StartPoint = point0;

    // Create the first line
    LineSegment seg1 = new LineSegment();
    seg1.Point = point1;
    pathFigure.Segments.Add(seg1);

    // Use an arc for the circular side
    ArcSegment seg2 = new ArcSegment();
    seg2.Point = point2;
    seg2.Size = new Size(RadiusX, RadiusY);
    seg2.RotationAngle = SliceCenterAngle;
    seg2.IsLargeArc = (SliceCenterAngle > 180.0);
    seg2.SweepDirection = SweepDirection.Counterclockwise;
    pathFigure.Segments.Add(seg2);

    // Close shape by going back to the starting point
    LineSegment seg3 = new LineSegment();
    seg3.Point = new Point(point0.X, point0.Y);
    pathFigure.Segments.Add(seg3);

    pathFigure.IsClosed = true;
    pathFigure.IsFilled = true;

    return pathFigure;
}

/// <summary>
/// Returns a point on the ellipse based on the rotationAngle, using
/// RadiusX/Y as the center (0, 0).
/// </summary>
private Point CalculatePointOnEllipse(double rotationAngle)
{
    double angleRadians = rotationAngle * Math.PI / 180.0;
    double x = Math.Cos(angleRadians);
    x = RadiusX * x;
    double y = Math.Sin(angleRadians);
    y = RadiusY * y;

    Point result = new Point(x, y);
    result.X = RadiusX - x;
    result.Y = RadiusY + y;
    return result;
}

Step 4: Going Forward

SpinningCursor1-TestPage Obviously this still needs a lot of improvement before it approaches the appeal of the Marble of Doom, which I will work on in the coming posts. However, the initial effort to create the "pizza" slices has been achieved and it is easier to build upon a base.

I added a grid in the background when I had some difficulty with the path geometry, but it is useful to I added two text boxes for the number of slices and rotation angle so that I could see the shape update dynamically.

Since I just used LineSegments to connect the slice points, the shape does not have the swirl or twist effect yet. Next time I will add the twist as well as rotation.

Technorati tags: ,

kick it on DotNetKicks.com

posted @ Monday, October 20, 2008 3:08 PM | Feedback (0) | Filed Under [ C# Programming SilverLight ]

Wednesday, October 08, 2008

Spinning Wait Symbol in Silverlight

My wife has a Treo with Windows Mobile and I when I was using it I noticed it had a cool rotating wait symbol, so I wondered how difficult it would be to build the symbol in Silverlight. The symbol is similar to the old BeOS wait cursor and has as well as the Mac OS X wait cursor which I've always thought looks nice. At one point in time I created a Windows cursor that duplicated the look of the BeOS cursor but I don't use it anymore. If I found a really nice looking 24-bit cursor then I might use it again.

Quadrant1The first step is to create the four quadrants. I used the path geometry to create each quadrant, for example the first quadrant is:

Data="M0,0 C0,0 100,0 100,100 L0,100 z"

For reference , the path markup syntax is documented at MSDN. The shape starts at (0,0) and creates a curve point with a control point at (100,0) and end point at (100,100). Then there is a LineTo (0,100) and finally the close ("z") marker to complete the shape. While this is fairly easy through a graphical editor such as Expression Blend (blog), I created this manually so that I could have more control over the exact coordinates rather than relying on the graphical editor.

I repeated the shape for each quadrant by adjusting the coordinates as necessary. It is also possible to simply apply a rotation to the shape so you have rotations of 90, 180, and 270 degrees, but remember to set the RenderTransformOrigin to the correct corner such as (0,1) to rotate by the bottom left corner.

Once the quadrants are built, then I placed a rotating quadrant named 'Spinner' over the combined shape. I used an alpha mask on the spinner to differentiate it from the other quadrants. Finally, I added a Storyboard to rotate the 'Spinner' 360 degrees every two seconds:

<Storyboard x:Name="SpinStoryboard" RepeatBehavior="Forever">
  <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Spinner"
      Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
    <SplineDoubleKeyFrame KeyTime="00:00:02" Value="360"/>
  </DoubleAnimationUsingKeyFrames>
</Storyboard>

The end result is a nice looking animation that is fairly simple. I'm tempted to try to duplicate the Mac OS X wait cursor, but that will have to wait until I have more time.

Spinning Cursor in Blend

kick it on DotNetKicks.com
Technorati tags:

posted @ Wednesday, October 08, 2008 8:03 AM | Feedback (1) | Filed Under [ C# SilverLight ]

Sunday, September 14, 2008

Bouncing Balls in Silverlight Part 1

BounceTest

Recently I wanted to make a very simple sample in Silverlight that used a little code to animate bouncing balls. The overall effect is fairly simple, but getting the sample down to the basics took a little time. As part of my research, I looked at several old bouncing ball demos using JavaScript and it was an eye-opening reminder of the dark ages of browsers and JavaScript.

For the sample, I wanted to keep everything very simple. I started with a circle (ellipse with the same height and width) in a canvas. In order to move the ball, I chose to position the ball at (0, 0) and use a TranslateTransform to adjust the position. You could easily move the ball around with Left and Top, but I also plan to use RotateTransform in later samples so it makes sense to use a TransformGroup to manipulate the object.

The XAML for the base page is just a Canvas and a rectangle that acts as a border. The ball is placed on the canvas using the common TransformGroup that is created by Expression Blend when you add a transform to an object. Expression Blend also uses the same order for the transforms (ScaleTransform, SkewTransform, RotateTransform, TranslateTransform) and will reorder the transforms back to this order if you adjust any transform using Blend (at least as of Blend 2.5 June 2008 Preview). Here is the XAML for the page:

<UserControl x:Class="BounceTest.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Canvas x:Name="LayoutRoot">
        <Rectangle x:Name="Boundary" Height="300" Width="400" 
            Canvas.Left="0" Canvas.Top="0"
            Fill="#FFFFFFFF" Stroke="#FF000000" />
        <Ellipse x:Name="Ball01" Height="25" Width="25"
            Canvas.Left="0" Canvas.Top="0"
            Fill="#FFEE3131" Stroke="#FF000000"
            RenderTransformOrigin="0.5,0.5">
            <Ellipse.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform X="50" Y="50"/>
                </TransformGroup>
            </Ellipse.RenderTransform>
        </Ellipse>
    </Canvas>
</UserControl>

I created a small class to manage the position and velocity of the ball. The constructor takes the source shape (the ball), the velocity, and the boundary shape. For this scenario, I assume that the ball already has the RotateTransform otherwise it throws an exception. The code could easily create a RotateTransform if it isn't present. The Update method takes the elapsed time since the previous method call. The boundary checking is extremely simple and just changes the direction of the motion when the ball hits a boundary edge. This obviously needs a lot of work for more complex scenarios, but it will do for this simple case.

public class ShapeVelocity
{
	public Shape shape;
	public Vector velocity;
	public TranslateTransform translate;
	public Size bounds;
	public Size container;

	public ShapeVelocity(Shape AShape, Vector AVelocity, Shape BoundsContainer)
	{
		this.shape = AShape;
		this.velocity = AVelocity;

		var renderTransform = this.shape.RenderTransform;
		if (renderTransform is TransformGroup)
		{
			TransformGroup transformGroup = (TransformGroup)renderTransform;
			foreach (Transform transform in transformGroup.Children)
				if (transform is TranslateTransform)
					this.translate = (TranslateTransform)transform;
		}
		if (this.translate == null)
			throw new ArgumentException("Shape must have a TranslateTransform in it");

		container = new Size(BoundsContainer.Width, BoundsContainer.Height);
		bounds = new Size(
			this.shape.ActualWidth + this.shape.StrokeThickness,
			this.shape.ActualHeight + this.shape.StrokeThickness);
	}

	public void Update(TimeSpan Interval)
	{
		Rect pos = new Rect(
			translate.X,
			translate.Y,
			bounds.Width,
			bounds.Height);

		if ((velocity.X < 0.0) && (pos.Left < 0.0))
			velocity.X = -velocity.X;
		else if ((velocity.X > 0.0) && (pos.Right > container.Width))
			velocity.X = -velocity.X;
		if ((velocity.Y < 0.0) && (pos.Top < 0.0))
			velocity.Y = -velocity.Y;
		else if ((velocity.Y > 0.0) && (pos.Bottom > container.Height))
			velocity.Y = -velocity.Y;

		translate.X += velocity.X * (double) Interval.Milliseconds / 1000.0;
		translate.Y += velocity.Y * (double) Interval.Milliseconds / 1000.0;
	}
}

In anticipation of future examples, I used a List<Shape> collection to store the ball shape to updae the position. For the motion, I used the StoryBoard instead of a DispatcherTimer based on the recommendation of Adam Kinney.

public partial class Page : UserControl
{
    private DateTime _lastTime = DateTime.MinValue;
    private double _initialSpeed = 50.0;
    private Storyboard _storyboard;
    private List<ShapeVelocity> _shapes;

    public Page()
    {
        InitializeComponent();
        _shapes = new List<ShapeVelocity>();
        _storyboard = new Storyboard();
        _storyboard.Duration = TimeSpan.FromMilliseconds(10);
        _storyboard.Completed += new EventHandler(storyboard_Tick);
        this.Loaded += new RoutedEventHandler(Page_Loaded);
    }

    void Page_Loaded(object sender, RoutedEventArgs e)
    {
        _shapes.Add(new ShapeVelocity(Ball01, new Vector(_initialSpeed, _initialSpeed), Boundary));
        _lastTime = System.DateTime.Now;
        _storyboard.Begin();
    }

    void storyboard_Tick(object sender, EventArgs e)
    {
        DateTime now = System.DateTime.Now;
        TimeSpan interval = now - _lastTime;
        foreach (ShapeVelocity s in _shapes)
        {
            s.Update(interval);
        }
        _lastTime = now;
        _storyboard.Begin();
    }
}

So that is the very simple bouncing ball sample.

Get Microsoft Silverlight