Sunday, 29 July 2007
Rotating Video Picture Board
You can view a demo or download the source at http://www.chrishay.com/silverlight/rotatingvideopictureboard/
I have been a little lazy and not included a downloader, so you will probably want to hit F5 and refresh the page once the video has downloaded.
I will probably extend this in the future and turn it into a game of some sort.
Yay Microsoft
I published an issue i was having Orcas last night and this morning i received a comment on the blog from the main web dude himself (Mr Scott Guthrie). He is proactively offering to get someone to look into it. This is very cool (especially since this a sunday morning).
I think this sort of attitude (and level of support), is what will make Microsoft and Silverlight absolutely dominate the world of web.
Go Microsoft, and Thanks
Saturday, 28 July 2007
Orcas Beta 2 Bug: Don't have Intellisense on my own controls
Not only do i not get intellisense for my control, but it also seems to break intellisense for everything else on that page
May'be I'm not doing something right but it's a little frustrating
Inheriting a control from the Silverlight 1.1 Alpha Refresh Control Toolkit
I was attempting to create my own button which inherits ButtonBase. I used Button as an example and discovered the following problem.
If you create your new control outside of the SilverlightUIControl project, and use an embedded xaml file, unfortunately your button will not work.
This is because ControlBase will only look at resources in the Assembly in the SilverlightUIControls assembly.
I have implemented a workaround (messy code, but nonetheless it does the job). I have posted it below (all you need to do is replace the constructor in ControlBase).
I hope the guys at MS fix this:
public ControlBase()
{
//the control template must be in an embeded resource - find it
Stream resourceStream = null;
//if the assembly is built with VS there will be a prefix before
//the resource name we expect. The resource name will be at the
//end after a dot
string dotResource = '.' + ResourceName;
Assembly assembly = typeof(ControlBase).Assembly;
string[] names = assembly.GetManifestResourceNames();
bool found = false;
foreach (string name in names) {
if (name.Equals(ResourceName) || name.EndsWith(dotResource)) {
resourceStream = assembly.GetManifestResourceStream(name);
found = true;
break;
}
}
if (!found)
{
Assembly currentAssembly = this.GetType().Assembly;
string[] currentNames = currentAssembly.GetManifestResourceNames();
foreach (string name in currentNames)
{
if (name.Equals(ResourceName) || name.EndsWith(dotResource))
{
resourceStream = currentAssembly.GetManifestResourceStream(name);
found = true;
break;
}
}
}
Debug.Assert(resourceStream != null, "the resource template" + ResourceName + " not found");
StreamReader sr = new StreamReader(resourceStream);
string xaml = sr.ReadToEnd();
actualControl = InitializeFromXaml(xaml);
sr.Close();
Debug.Assert(actualControl != null, "failed to initialize the control");
base.Width = actualControl.Width;
base.Height = actualControl.Height;
Loaded += new EventHandler(OnLoaded);
}
Friday, 27 July 2007
New Release of Silverlight for Orcas Beta 2
Thursday, 26 July 2007
Visual Studio 2008 (Orcas) Beta 2 available for download
Yay, go Microsoft!
It is now happily downloading on my machine ready for me to play with over the weekend.
As I said in my previous post, it is time to install it on my work machine (targeted at .NET Framework 3.0).
Monday, 23 July 2007
Silverlight Color Table
If you wish to see a bitmap of the color's you can click here
I thought it might be useful to have a XAML file which we can load in SilverlightPad, Blend or whatever you use to view each color in its rendered format.
Here is the XAML below:
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="MainCanvas" Height="500" Width="500">
<Canvas>
<TextBlock Canvas.Top="0" Foreground="AliceBlue" Text="AliceBlue"/>
<TextBlock Canvas.Top="20" Foreground="AntiqueWhite" Text="AntiqueWhite"/>
<TextBlock Canvas.Top="40" Foreground="Aqua" Text="Aqua"/>
<TextBlock Canvas.Top="60" Foreground="AquaMarine" Text="AquaMarine"/>
<TextBlock Canvas.Top="80" Foreground="Azure" Text="Azure"/>
<TextBlock Canvas.Top="100" Foreground="Beige" Text="Beige"/>
<TextBlock Canvas.Top="120" Foreground="Bisque" Text="Bisque"/>
<TextBlock Canvas.Top="140" Foreground="Black" Text="Black"/>
<TextBlock Canvas.Top="160" Foreground="BlanchedAlmond" Text="BlanchedAlmond"/>
<TextBlock Canvas.Top="180" Foreground="Blue" Text="Blue"/>
<TextBlock Canvas.Top="200" Foreground="BlueViolet" Text="BlueViolet"/>
<TextBlock Canvas.Top="220" Foreground="Brown" Text="Brown"/>
<TextBlock Canvas.Top="240" Foreground="BurlyWood" Text="BurlyWood"/>
<TextBlock Canvas.Top="260" Foreground="CadetBlue" Text="CadetBlue"/>
<TextBlock Canvas.Top="280" Foreground="Chartreuse" Text="Chartreuse"/>
<TextBlock Canvas.Top="300" Foreground="Chocolate" Text="Chocolate"/>
<TextBlock Canvas.Top="320" Foreground="Coral" Text="Coral"/>
<TextBlock Canvas.Top="340" Foreground="CornflowerBlue" Text="CornflowerBlue"/>
<TextBlock Canvas.Top="360" Foreground="Cornsilk" Text="Cornsilk"/>
<TextBlock Canvas.Top="380" Foreground="Crimson" Text="Crimson"/>
<TextBlock Canvas.Top="400" Foreground="Cyan" Text="Cyan"/>
<TextBlock Canvas.Top="420" Foreground="DarkBlue" Text="DarkBlue"/>
<TextBlock Canvas.Top="440" Foreground="DarkCyan" Text="DarkCyan"/>
<TextBlock Canvas.Top="460" Foreground="DarkGoldenrod" Text="DarkGoldenrod"/>
<TextBlock Canvas.Top="480" Foreground="DarkGray" Text="DarkGray"/>
<TextBlock Canvas.Top="500" Foreground="DarkGreen" Text="DarkGreen"/>
<TextBlock Canvas.Top="520" Foreground="DarkKhaki" Text="DarkKhaki"/>
<TextBlock Canvas.Top="540" Foreground="DarkMagenta" Text="DarkMagenta"/>
<TextBlock Canvas.Top="560" Foreground="DarkOliveGreen" Text="DarkOliveGreen"/>
<TextBlock Canvas.Top="580" Foreground="DarkOrange" Text="DarkOrange"/>
<TextBlock Canvas.Top="600" Foreground="DarkOrchid" Text="DarkOrchid"/>
<TextBlock Canvas.Top="620" Foreground="DarkRed" Text="DarkRed"/>
<TextBlock Canvas.Top="640" Foreground="DarkSalmon" Text="DarkSalmon"/>
<TextBlock Canvas.Top="660" Foreground="DarkSeaGreen" Text="DarkSeaGreen"/>
<TextBlock Canvas.Top="680" Foreground="DarkSlateBlue" Text="DarkSlateBlue"/>
<TextBlock Canvas.Top="700" Foreground="DarkSlateGray" Text="DarkSlateGray"/>
</Canvas>
<Canvas Canvas.Left="150">
<TextBlock Canvas.Top="0" Foreground="DarkTurquoise" Text="DarkTurquoise"/>
<TextBlock Canvas.Top="20" Foreground="DarkViolet" Text="DarkViolet"/>
<TextBlock Canvas.Top="40" Foreground="DeepPink" Text="DeepPink"/>
<TextBlock Canvas.Top="60" Foreground="DeepSkyBlue" Text="DeepSkyBlue"/>
<TextBlock Canvas.Top="80" Foreground="DimGray" Text="DimGray"/>
<TextBlock Canvas.Top="100" Foreground="DodgerBlue" Text="DodgerBlue"/>
<TextBlock Canvas.Top="120" Foreground="Firebrick" Text="Firebrick"/>
<TextBlock Canvas.Top="140" Foreground="FloralWhite" Text="FloralWhite"/>
<TextBlock Canvas.Top="160" Foreground="ForestGreen" Text="ForestGreen"/>
<TextBlock Canvas.Top="180" Foreground="Fuchsia" Text="Fuchsia"/>
<TextBlock Canvas.Top="200" Foreground="Gainsboro" Text="Gainsboro"/>
<TextBlock Canvas.Top="220" Foreground="GhostWhite" Text="GhostWhite"/>
<TextBlock Canvas.Top="240" Foreground="Gold" Text="Gold"/>
<TextBlock Canvas.Top="260" Foreground="Goldenrod" Text="Goldenrod"/>
<TextBlock Canvas.Top="280" Foreground="Gray" Text="Gray"/>
<TextBlock Canvas.Top="300" Foreground="Green" Text="Green"/>
<TextBlock Canvas.Top="320" Foreground="GreenYellow" Text="GreenYellow"/>
<TextBlock Canvas.Top="340" Foreground="Honeydew" Text="Honeydew"/>
<TextBlock Canvas.Top="360" Foreground="HotPink" Text="HotPink"/>
<TextBlock Canvas.Top="380" Foreground="IndianRed" Text="IndianRed"/>
<TextBlock Canvas.Top="400" Foreground="Indigo" Text="Indigo"/>
<TextBlock Canvas.Top="420" Foreground="Ivory" Text="Ivory"/>
<TextBlock Canvas.Top="440" Foreground="Khaki" Text="Khaki"/>
<TextBlock Canvas.Top="460" Foreground="Lavender" Text="Lavender"/>
<TextBlock Canvas.Top="480" Foreground="LavenderBlush" Text="LavenderBlush"/>
<TextBlock Canvas.Top="500" Foreground="LawnGreen" Text="LawnGreen"/>
<TextBlock Canvas.Top="520" Foreground="LemonChiffon" Text="LemonChiffon"/>
<TextBlock Canvas.Top="540" Foreground="LightBlue" Text="LightBlue"/>
<TextBlock Canvas.Top="560" Foreground="LightCoral" Text="LightCoral"/>
<TextBlock Canvas.Top="580" Foreground="LightCyan" Text="LightCyan"/>
<TextBlock Canvas.Top="600" Foreground="LightGoldenrodYellow" Text="LightGoldenrodYellow"/>
<TextBlock Canvas.Top="620" Foreground="LightGray" Text="LightGray"/>
<TextBlock Canvas.Top="640" Foreground="LightGreen" Text="LightGreen"/>
<TextBlock Canvas.Top="660" Foreground="LightPink" Text="LightPink"/>
<TextBlock Canvas.Top="680" Foreground="LightSalmon" Text="LightSalmon"/>
</Canvas>
<Canvas Canvas.Left="300">
<TextBlock Canvas.Top="0" Foreground="LightSeaGreen" Text="LightSeaGreen"/>
<TextBlock Canvas.Top="20" Foreground="LightSkyBlue" Text="LightSkyBlue"/>
<TextBlock Canvas.Top="40" Foreground="LightSlateGray" Text="LightSlateGray"/>
<TextBlock Canvas.Top="60" Foreground="LightSteelBlue" Text="LightSteelBlue"/>
<TextBlock Canvas.Top="80" Foreground="LightYellow" Text="LightYellow"/>
<TextBlock Canvas.Top="100" Foreground="Lime" Text="Lime"/>
<TextBlock Canvas.Top="120" Foreground="LimeGreen" Text="LimeGreen"/>
<TextBlock Canvas.Top="140" Foreground="Linen" Text="Linen"/>
<TextBlock Canvas.Top="160" Foreground="Magenta" Text="Magenta"/>
<TextBlock Canvas.Top="180" Foreground="Maroon" Text="Maroon"/>
<TextBlock Canvas.Top="200" Foreground="MediumAquamarine" Text="MediumAquamarine"/>
<TextBlock Canvas.Top="220" Foreground="MediumBlue" Text="MediumBlue"/>
<TextBlock Canvas.Top="240" Foreground="MediumOrchid" Text="MediumOrchid"/>
<TextBlock Canvas.Top="260" Foreground="MediumPurple" Text="MediumPurple"/>
<TextBlock Canvas.Top="280" Foreground="MediumSeaGreen" Text="MediumSeaGreen"/>
<TextBlock Canvas.Top="300" Foreground="MediumSlateBlue" Text="MediumSlateBlue"/>
<TextBlock Canvas.Top="320" Foreground="MediumSpringGreen" Text="MediumSpringGreen"/>
<TextBlock Canvas.Top="340" Foreground="MediumTurquoise" Text="MediumTurquoise"/>
<TextBlock Canvas.Top="360" Foreground="MediumVioletRed" Text="MediumVioletRed"/>
<TextBlock Canvas.Top="380" Foreground="MidnightBlue" Text="MidnightBlue"/>
<TextBlock Canvas.Top="400" Foreground="MintCream" Text="MintCream"/>
<TextBlock Canvas.Top="420" Foreground="MistyRose" Text="MistyRose"/>
<TextBlock Canvas.Top="440" Foreground="Moccasin" Text="Moccasin"/>
<TextBlock Canvas.Top="460" Foreground="NavajoWhite" Text="NavajoWhite"/>
<TextBlock Canvas.Top="480" Foreground="Navy" Text="Navy"/>
<TextBlock Canvas.Top="500" Foreground="OldLace" Text="OldLace"/>
<TextBlock Canvas.Top="520" Foreground="Olive" Text="Olive"/>
<TextBlock Canvas.Top="540" Foreground="OliveDrab" Text="OliveDrab"/>
<TextBlock Canvas.Top="560" Foreground="Orange" Text="Orange"/>
<TextBlock Canvas.Top="580" Foreground="OrangeRed" Text="OrangeRed"/>
<TextBlock Canvas.Top="600" Foreground="Orchid" Text="Orchid"/>
<TextBlock Canvas.Top="620" Foreground="PaleGoldenrod" Text="PaleGoldenrod"/>
<TextBlock Canvas.Top="640" Foreground="PaleGreen" Text="PaleGreen"/>
<TextBlock Canvas.Top="660" Foreground="PaleTurquoise" Text="PaleTurquoise"/>
<TextBlock Canvas.Top="680" Foreground="PaleVioletRed" Text="PaleVioletRed"/>
</Canvas>
<Canvas Canvas.Left="450">
<TextBlock Canvas.Top="0" Foreground="PapayaWhip" Text="PapayaWhip"/>
<TextBlock Canvas.Top="20" Foreground="PeachPuff" Text="PeachPuff"/>
<TextBlock Canvas.Top="40" Foreground="Peru" Text="Peru"/>
<TextBlock Canvas.Top="60" Foreground="Pink" Text="Pink"/>
<TextBlock Canvas.Top="80" Foreground="Plum" Text="Plum"/>
<TextBlock Canvas.Top="100" Foreground="PowderBlue" Text="PowderBlue"/>
<TextBlock Canvas.Top="120" Foreground="Purple" Text="Purple"/>
<TextBlock Canvas.Top="140" Foreground="Red" Text="Red"/>
<TextBlock Canvas.Top="160" Foreground="RosyBrown" Text="RosyBrown"/>
<TextBlock Canvas.Top="180" Foreground="RoyalBlue" Text="RoyalBlue"/>
<TextBlock Canvas.Top="200" Foreground="SaddleBrown" Text="SaddleBrown"/>
<TextBlock Canvas.Top="220" Foreground="Salmon" Text="Salmon"/>
<TextBlock Canvas.Top="240" Foreground="SandyBrown" Text="SandyBrown"/>
<TextBlock Canvas.Top="260" Foreground="SeaGreen" Text="SeaGreen"/>
<TextBlock Canvas.Top="280" Foreground="SeaShell" Text="SeaShell"/>
<TextBlock Canvas.Top="300" Foreground="Sienna" Text="Sienna"/>
<TextBlock Canvas.Top="320" Foreground="Silver" Text="Silver"/>
<TextBlock Canvas.Top="340" Foreground="SkyBlue" Text="SkyBlue"/>
<TextBlock Canvas.Top="360" Foreground="SlateBlue" Text="SlateBlue"/>
<TextBlock Canvas.Top="380" Foreground="SlateGray" Text="SlateGray"/>
<TextBlock Canvas.Top="400" Foreground="Snow" Text="Snow"/>
<TextBlock Canvas.Top="420" Foreground="SpringGreen" Text="SpringGreen"/>
<TextBlock Canvas.Top="440" Foreground="SteelBlue" Text="SteelBlue"/>
<TextBlock Canvas.Top="460" Foreground="Tan" Text="Tan"/>
<TextBlock Canvas.Top="480" Foreground="Teal" Text="Teal"/>
<TextBlock Canvas.Top="500" Foreground="Thistle" Text="Thistle"/>
<TextBlock Canvas.Top="520" Foreground="Tomato" Text="Tomato"/>
<TextBlock Canvas.Top="540" Foreground="Transparent" Text="Transparent"/>
<TextBlock Canvas.Top="560" Foreground="Turquoise" Text="Turquoise"/>
<TextBlock Canvas.Top="580" Foreground="Violet" Text="Violet"/>
<TextBlock Canvas.Top="600" Foreground="Wheat" Text="Wheat"/>
<TextBlock Canvas.Top="620" Foreground="White" Text="White"/>
<TextBlock Canvas.Top="640" Foreground="WhiteSmoke" Text="WhiteSmoke"/>
<TextBlock Canvas.Top="660" Foreground="Yellow" Text="Yellow"/>
<TextBlock Canvas.Top="680" Foreground="YellowGreen" Text="YellowGreen"/>
</Canvas>
</Canvas>
Visual Studio 2008 (Orcas) Beta 2 Release Date
He reckoned that Beta 2 would be released within 3 weeks (dated 9th of July). He also reckoned that it would include a Go Live License.
Now if we couple that with Multi-Targetting support, there is no reason not to move to Beta 2 (in my own humble opinion), even in production environments (as long as we target earlier versions of the framework).
The real question is risks and balances of when to target .NET Framework 3.5
UPDATE: Obviously Beta 2 has now been released. For a full list of click here for further release dates of Visual Studio 2008, Sql Server 2008, Silverlight etc
Friday, 20 July 2007
Silverlight Pad
If you are a developer (not a designer), and you want to mock up some XAML without going to the hassle of bringing up Blend or Designer then this is a great tool.
ASP.NET Details View and Object Source
For example if binding to an object you can bind to a property as normal. If you wish to display a property which is a member of an object which is a member of the object you are binding to (it complains).
Here is a simple way around it:
<asp:DetailsView ID="dv" runat="server" AutoGenerateRows="False">
<Fields>
<asp:BoundField DataField="MyProperty" HeaderText="MyProperty" />
<asp:TemplateField HeaderText="My Object Property"><ItemTemplate><%# Eval("MyObject.MyObjectProperty")%></ItemTemplate></asp:TemplateField>
</Fields>
</asp:DetailsView>
Another quick point if you wish to bind an object to a details view (for example) using object source. Just add the object to a list.
Here is a VB sample showing what i mean (I like to switch examples around occasionally):
Dim myItems As New List(Of Item)
myItems.Add(item)
dv.DataSource = tasks
dv.DataBind()
Wednesday, 18 July 2007
C# As, Is and Cast
Use of "as" and "is" will sort this out.
If you are casting a reference type use "as":
string bob = dr["bob"] as string;
If using a value type use "is" first
DateTime currentTime = DateTime.MinValue;
if (dr["currentTime"] is DateTime)
{
currentTime = (DateTime)dr["currentTime"];
}
This means that you shouldn't end up with DBNull casting errors.
Friday, 13 July 2007
TFS and Custom Tasks
I decided I wanted the tasks to be more flexible. I came across this article which explains how to extend your tasks to take input parameters.
Thursday, 12 July 2007
C# / XML Code Formatter for Blogs
http://www.manoli.net/csharpformat/
Using the changeset
In this post I will show you how to modify that code to modify that task to use the changeset number as the build number (which is virtually incremental in a CI environment).
Simply reference the Team Foundation Server Assemblies required for the following using statements:
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
And now simply use this little method to get the changeset number:
private int GetLatestChangeSetId()
{
// Get a reference to our Team Foundation Server.
string tfsName = @"http://myserver:8080";
TeamFoundationServer tfs = new TeamFoundationServer(tfsName);
// Get a reference to Version Control.
VersionControlServer versionControl = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
int latestChangesetId = versionControl.GetLatestChangesetId();
return latestChangesetId;
}
CI (Continuous Integration) Builds
There are a couple of points i wish to make beyond this article.
1) You can keep a nightly build as well as a CI build. This is very useful, we use the CI build to verify checkin, but the Nightly build to deployment to the test team.
2) You can use the nightly build to get all sources from source and do a full build, and the CI build to give an incremental build.
I think this strategy gives the best of both worlds.
If you wish to set your CI build as an incremental build you should do the following.
Within the tfsbuild.proj file, add the following (within the ProjectExtensions Tag):
<SkipClean>true</SkipClean>
<SkipInitializeWorkspace>true</SkipInitializeWorkspace>
<ForceGet>false</ForceGet>
This will stop TFS from reinitalising workspaces, and regetting all sources.
Overriding the TFS Build Number
This is a useful article, and something I have just implemented.
This allows you to override the TFS build number, to generate a build number based on Ticks of the Current Time.
http://msdn2.microsoft.com/EN-US/library/aa395241(VS.80).aspx
This now allows us to have a single build number which we can use, record and track bugs against.
Wednesday, 11 July 2007
TFS and Continuous Integration (CI)
http://msdn2.microsoft.com/en-us/library/ms364045(VS.80).aspx
This includes an MSI to install on the TFS and some simple configuration.
I would recommend creating a new CI Build Type in TFS that uses incremental updates (I will discuss this in another article)
It is also worth keeping a full nightly build also.
TFS and Web Application Projects
I found this useful snippet of information on the Microsoft Website regarding TFS builds for Web Application Projects.
The May 2006 release of Web Application Projects supports building with Team Build on a Team Foundation Server (TFS). However, you will need to manually add the "Microsoft.WebApplication.targets" file to your Team Foundation Server for it to work.
- On the computer running Team Build, navigate to the "C:\Program Files\MSBuild\Microsoft\VisualStudio\v8.0" directory.
- In this directory create a "WebApplications" directory.
- Place the "Microsoft.WebApplication.targets" file in the "WebApplications" directory. This file can be found at the same location on your developer system that has been updated with the May 2006 release of Web Application Projects.
After performing these steps Team Build should be able to successfully build a web-project build with the new Web Application Project type.
Scheduling a TFS Build
The syntax for the command line utility TFSBuild is:
TFSBuild start Teamfoundationserver TeamProject BuildType [/machine:buildmachine] [/builddirectory:builddirectory]
For Example:
TFSBuild Start MyBuildServer MyTeamProject MyBuildType
Cancelling a TFS Build
To kill the MSBuild Process on the Build Server.
I do wish Microsoft would give you this option from within Team Foundation Client
Tuesday, 10 July 2007
Properties / Fields and the JIT
I seem to be spending to much time talking about properties but I feel it is important to get a deep understanding of what is going on.
The final point I wish to get back to is that when discussing Properties Vs Fields, I indicated there is a slight performance hit when using a property rather than a field, since a property is really a method.
Whilst this is true in debug mode, it is not true when released.
The reason for this is that our friend the JIT, will replace all calls to property methods with the actual code.
Therefore in my very humble opinion, there is less and less of a reason to use
fields, rather than properties (especially in a world of automatic properties)
Thursday, 5 July 2007
ASP.NET Internal Development Web Server Command Line Usage
This will allow you to start the web server from the command line, make your changes, build your changes, and reattach to the debugger.
Edit and Continue is lovely (but not if you want to change class definitions).
I've included and example call to start the Web Server below:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer /port:4567 /path:"C:\Source\MyWebProject"
Wednesday, 4 July 2007
Fading Rectangly thingy Silverlight XAML Animation
We have four squares rotating and fading, to build a larger square (looks quite pretty).
The XAML is below.
I will look into hosting these somewhere at some point
<Canvas>
<Canvas.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="myRectangleRotate1" Storyboard.TargetProperty="Angle" To="90" Duration="0:0:01"/>
<DoubleAnimation Storyboard.TargetName="myRectangleRotate2" Storyboard.TargetProperty="Angle" To="180" Duration="0:0:02"/>
<DoubleAnimation Storyboard.TargetName="myRectangleRotate3" Storyboard.TargetProperty="Angle" To="270" Duration="0:0:03"/>
<DoubleAnimation Storyboard.TargetName="myRectangleRotate4" Storyboard.TargetProperty="Angle" To="360" Duration="0:0:04"/>
<DoubleAnimation Storyboard.TargetName="myRectangle1" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:04"/>
<DoubleAnimation Storyboard.TargetName="myRectangle2" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:04"/>
<DoubleAnimation Storyboard.TargetName="myRectangle3" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:04"/>
<DoubleAnimation Storyboard.TargetName="myRectangle4" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:04"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Canvas.Triggers>
<TextBlock x:Name="helloBlock" Foreground="SlateBlue"/>
<Rectangle x:Name="myRectangle1" Height="100" Width="100" Canvas.Left="200" Canvas.Top="200"
Fill="SlateBlue" Opacity="0">
<Rectangle.RenderTransform>
<RotateTransform x:Name="myRectangleRotate1" Angle="0"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="myRectangle2" Height="100" Width="100" Canvas.Left="200" Canvas.Top="200"
Fill="SlateBlue" Opacity="0">
<Rectangle.RenderTransform>
<RotateTransform x:Name="myRectangleRotate2" Angle="0"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="myRectangle3" Height="100" Width="100" Canvas.Left="200" Canvas.Top="200"
Fill="SlateBlue" Opacity="0">
<Rectangle.RenderTransform>
<RotateTransform x:Name="myRectangleRotate3" Angle="0"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle x:Name="myRectangle4" Height="100" Width="100" Canvas.Left="200" Canvas.Top="200"
Fill="SlateBlue" Opacity="0">
<Rectangle.RenderTransform>
<RotateTransform x:Name="myRectangleRotate4" Angle="0"/>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
Tuesday, 3 July 2007
Developing against Silverlight 1.1 Alpha in Visual Studio 2005
Don't get me wrong i love using orcas but it's not always practical to run up the Virtual Machine, when i just want to play around.
Here is how to use Silverlight 1.1 in 2005
1) Use a class project
2) remove all references
3) Project Properties->Build Tab->Advanced->Check 'Do not reference mscorlib.dll'
4) Add References to mscorlib, agclr, System, ,System.Core, System.Silverlight, and System.Xml.Core from the Silverlight folder (Microsoft Silverlight directory within Program Files)
5) Ensure the references are not copied to the output directory
6) Ensure the approriate content is copied to output directory (including your xaml file)
7) Ensure the xaml file build action (properties in visual studio) is set to content.
Properties Vs Fields
Arguments for making all fields private, and using properties:
1) If you have to promote a field to a property any dependant classes will require a recompile.
2) If you wish to use databinding, you need to use a property.
Arguments for using fields rather than properties
1) Slightly better performance (direct access), rather than access through an accessor method
2) More often than not you don't databind directly to a property (so only promote when required)
3) More often than not when we build and release, we build and release all components (unless you are a component developer_
4) More maintainable code (easier to look at than great big hulking property declarations, (not really an issue in a world of automatic properties)
5) Lazy Coding.
I think my preference is fairly clear (properties and automatic properties are good), but I understand if you want to use fields.
I think in a world of automatic properties, fields will not be used as often. I believe this because most coders are lazy (me included). Since automatic properties are so easy to implement there is less reason not use them (apart from those with strong opinions on using fields).
Automatic Properties (Continued)
It has been asked, "How do i access the private field"? Unfortunately you can't (you would need to use the normal property declaration to do that).
The private field is automatically generated by the compiler (which you do not have access to). If you wish to look at the private field declaration use ILDASM.
TODO: ILDASM Screenshot
Since you do not have access to the autogenerated private field, you will always been modifying its data through its accessors rather than directly.
Although has a slight performance hit, this inturn will produce more maintainable code.
Monday, 2 July 2007
Automatic Properties
More often that not, when we expose a property in a class, there is no extra logic within that class, and the property is just a wrapper to a private field. This means we end up with verbose code such as:
public class JobPosting
{
private string _jobTitle;
public string JobTitle
{
get
{
return _jobTitle;
}
set
{
_jobTitle = value;
}
}
}
There is no logic implemented in the property (defined in the example above) and it just acts as a wrapper. Automatic properties allows us to define the same code as above, but in a much prettier fashion.
The following snippet gives an example of the same class as before, but this time in Orcas syntax:
public class JobPosting
{
public string JobTitle { get;set;}
}
As you can see this, is much more readable and compact.
It is important to note that this new orcas style of implementation is NOT equivalent to a field as the compiler will produce the get, set blocks for you. This means that if you do have to implement some logic within your properties, you can use a full get,set block and any external code that uses your class will not require a recompile as the default public interface hasn't changed.
This superb little feature both reduces typing time, improves readability and makes happy little coders.
Roll on Orcas.