Exaggeration, perhaps, but so are those pretentious Mac vs PC commercials :)
Original here.
[Edit: Looks like this version of community server doesn't allow object tags, so just follow the link to view the video]
I've had a number of folks request I provide a walkthrough and/or source code for the chat application demo I did at the CMAP Spring Code Camp, so I put together this two part series. This is essentially the same demo I do live. Total time it takes me when presenting live is about 1 hour, assuming the sockets code is mostly pre-built. If you're new to Expression Design or Expression Blend, it will take you a bit longer.
Part 1 covers the design and animation of the chat balloon while Part 2 focuses on building the main window and developing the code to make the chat application work, including the chat server and the local client sockets code.
Project
I like to start my projects in Visual Studio. Some folks like to start them in Expression Blend. Either will typically work.
Create a standard C# Silverlight 2 application. If you are unsure as to how to do this, please visit the Get Started section of Silverlight.net to get the tools, and then and look through some of the tutorials in the Learn section.
ChatBalloon Control
While in Visual Studio, add a Silverlight UserControl and name it "ChatBalloon". You can also create the control in Blend if you prefer (and take advantage of the d:DesignXyz properties), but I'm most comfortable with doing all my project/file management in Visual Studio and using Blend just to work on files I've already created.
Next edit the Xaml in this control to have a height or 75, width of 300 and transparent background
<UserControl x:Class="PeteBrown.SilverlightChat.ChatBalloon"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="300" Height="75">
<Grid x:Name="LayoutRoot" Background="Transparent">
</Grid>
</UserControl>
User Interface
Creating the Chat Balloon in Expression Design
For the chat balloon, we want to end up with a shape that looks something like this:
Open up Expression Design 2 Beta and create a new file sized around 300x75 pixels
Basic Shape
Next, create a rectangle that takes up the entire available canvas. For the fill in that rectangle, select a gradient between two shades of the same color. Finally, set the corner radius of the rectangle to 12. You should end up with something that looks like this:
Next, we want to transform the gradient so it is vertical rather than horizontal. To do that, select the gradient transform tool (or press the "G" key) and click the top of the rectangle and drag to the bottom.
The next step is to duplicate the shape to create the "glass effect" overlay. Select the whole shape then hit Edit->Copy then Edit->Paste In Front. Check your layers to see that you now have two identical shapes.
Select the top-most shape and name it "Highlight". Select the bottom shape and name it "Background"
We'll come back to the Highlight shape in a moment.
Callout
Next, we're going to edit the Background shape to create the little callout point.
Select the Background shape and choose the "Add Anchor Point" tool (or press the "=" key)
Next add three anchor points at the bottom in roughly the center of the shape. You should end up with something like this:
Next, click the "Direct Selection" tool (or press the "A" key). We're going to drag the center point out to create a call-out for the chat balloon. You should see something like this
Now that we're done with the basic shape, we're going to create the glass effect
Glass Effect
Select the Highlight shape in the layers pane
Clear the stroke of that shape by selecting the stroke tab in the appearance pane and selecting "none" (the white box with the red line through it)
Next we'll change the Highlight gradient to give us a subtle overlay. I like to use white to white to allow me to change the background color without messing with the gradient.
You can experiment with various opacity values for the two stops in the gradient. In this example, I'm using 10% and 50% as the two stops, with 50% being the bottom value.
Next we'll change the shape so we can have have a strong line between our highlight and background.
With Highlight selected, select the "Delete Anchor Point" tool (or press the "-" key)
Now remove these points by clicking on them:
You should end up with a shape that looks like this:
Now, that might work, but it isn't very interesting, so let's add a little curve to the dividing line.
Select the "Add Anchor Point" (or press the "=" key) and then click on the center of the dividing line to bisect that line.
Now click the "Convert Anchor Point" tool (or press Shift+C). and click the point you just added.
Go back to the Direct Selection tool (A) and drag the point up just a little. You should end up with something like this:
At this point, you can play with the gradient transform or the opacities until you get the effect you were looking for. This is what I ended up with:
Creating the UI in Expression Blend
Building up the Chat Balloon
The first thing you'll want to do is export from Design the Xaml for the Chat Balloon. If you primarily work in Silverlight and not WPF, there's a quick trick to this. In the options for Design (Edit->Options->Clipboard (XAML)), select the option to use a Silverlight Canvas for the clipboard format.
Once you do that, you can simply select the object, then choose Edit->Copy Xaml to nab the Xaml from your designs.
Whichever way you prefer, nab the Xaml for the shape and paste it inside the LayoutRoot of our ChatBalloon control
Since the namespaces (xmlns and xmlns:x) are already defined, you can remove them from the canvas declaration that Design includes by default.
<Grid x:Name="LayoutRoot" Background="Transparent">
<Canvas x:Name="Layer_1" Width="300" Height="75" ...
<Path x:Name="Background" Width="301" Height="98.25" ...
<Path.Fill>
<LinearGradientBrush StartPoint="0.485833,0" ...
<LinearGradientBrush.RelativeTransform>
...
I tend to edit xaml inside Visual Studio. You can also use Expression Blend for that task if you wish.
Now, save your solution and open it up in Expression Blend 2.5. Open up the ChatBalloon.xaml file in design mode.
The first thing we want to do is add a grid to the layout.
Make LayoutRoot the current container by double-clicking it in the Objects list.
Next, add a grid to the control. You should have something like this:
Next, double-click the newly-added grid in the object tree to make it our current container. Hover over the grid layout bar in the design view and create a column in the grid. You should have a roughly photo-sized column to the left (just shy of square) and a larger area on the right that will contain the text.
Next, we'll add an image control to the left and a textblock to the right.
First, find the image control in the asset library. If it doesn't show up by default, make sure the "Show All" option is checked.
Create an image element in the left-most column. While not essential for this example, make sure that it is inside the grid you created and has a row and column of 0. You can double-check this by looking where it is in the object tree and by looking at the row and column properties in the layout pane.
Name the image ChatImage
Now, add a TextBlock to the second column in the same way. Double check that its row is 0 and its column is 1.
Change the font size to 12 and name it ChatMessage
In the end, you should have something like this:
Now would be a good time to save your project in Blend.
Pop and Fade Animation
Next we're going to create an animation that will pop the chat balloon up from near the bottom of the screen, hold it in place for a couple seconds, and then fade it off into the background.
To do this, we're going to combine scale and translate transforms with an opacity animation.
First, in the Objects and Timeline pane, click the button to add a new Storyboard
Name the storyboard PopAndFade.
You'll notice your workspace get suddenly cramped as it is put into animation recording mode. Switch to the animation workspace by hitting F6 or selecting Window->Active Workspace->Animation Workspace. You should see something like this:
The next thing we want to do is record a keyframe at 1/2 second with everything in its current position. The way you do this is, with Layer_1 (the canvas generated from Design) and the two-column grid selected, move the mouse around the numbers in the timeline and notice the playhead position indicator move with you. When it is on 1/2 second, click the "Record Keyframe" button. You should see a little egg appear in the Layer1 and grid timelines indicating a recorded keyframe.
Next, move the playhead position back to 0 so we can reposition and resize our objects.
With Layer_1 and the grid still selected, move them down and to the left, like this:
The keyframe will be recorded for you automatically.
With the playhead still at the zero second mark, open the Transform pane and set the scale to 0 for both X and Y.
If you play your animation, you should see it change size and position, popping up from the bottom left to the actual position of the control. Our animation is halfway there!
Next, we want to adjust the curve to give it more of a pop. Select the 1/2 second keyframe "eggs" for both Layer_1 and grid (click one then shift-click the other) to see the keyframe properties. In the easing curve. Adjust the easing curve by manipulating the control points until you have something resembling an "S". Rewind and play your animation while you adjust so you can see the effect of the easing curve.
The effect you're trying to achieve is something more like a "pop" than a straight boring linear interpolation.
Next, we want to slowly fade the balloon into the background. For this, we'll vary size, position and opacity.
Move the playhead position to 10 seconds mark and select Layer_1 and the grid again. 10 seconds is going to be the end of the animation.
Next, move the elements to the top left, but not too far up. You should see something like this:
Next, while still at the same playhead position and with the same items still selected, change the scale to .75 for both X and Y
Continuing with the same items selected and the same point in the timeline, set the opacity to 0. The end result will look like this:
For the final part of this animation, we'll want to change the easing curves for the keyframes at the 10 second mark. The curve illustrated below will cause the animation to accelerate as it gets towards the end. For the fade and resize, I think this is appropriate. Feel free to change this curve to anything that you like, as long as you take into account the time required to read the message.
Our animation is done. To test it out, rewind the animation and play it from the start.
The animation and the majority of the design is now complete. Save your project at this point and stay tuned for Part 2.
In Part 2, we'll build the main UI and wire this up with some real communications and a socket server to make a functional demo chat application.
On Wednesday April 30 at 2:00PM Eastern time, Marc Schweigert from Microsoft will present a webcast on the ASP.NET 3.5 extensions preview.
I've known Marc for a long time, and have presented with him on a number of occasions both online and in-person. He's a great speaker and always has jam-packed demos (he slings more code in an hour than just about anyone else I've seen).
This webcast will be a sure thing if you're interested in the new bits coming out for:
- ASP.NET MVC
- ASP.NET Dynamic Data
- ASP.NET AJAX
- ADO.NET Entity Framework
- ADO.NET Data Services
- and, of course, Silverlight Controls for ASP.NET
Read more and register here.
Eugene Osovetsky made a pretty exciting announcement yesterday regarding pushing data to Silverlight in Beta 2.
Beta 2 will likely include a new WCF capability for duplex services based on DuplexReceiver<T>. IMHO, this helps eliminate socket coding for some of the more common scenarios:
- Chat applications
- Data update notifications in biz apps
There will be both a client (Silverlight) and a server (WCF) component to this. In the spirit of keeping Silverlight's core platform agnostic, the client-side piece will be shipped as an extension assembly that you can include in your application as needed.
Having gone the socket route for a chat application demo I wrote (screenshot above), this is a very welcome addition. I was never proud of the sockets mush I put together in that (which is why the source is by-request only, I don't think it was a good pattern to follow), and would be happy to convert it to this new pattern.
Keep in mind this is all pre-release information and may or may not reflect what finally shows up in Beta 2 or RTW.
More information on Eugene's blog here.
While it isn't ready to roll out just yet, I've decided to convert my blog and main site over to Graffiti CMS. The folks at Telligent have put together quite a platform for individual blogging and content management. Despite that, the "CMS" in the product name stands for "Content Made Simple", not "Content Management System". If you've ever used a full-blown CMS, you'll understand why.
The screenshot on the right is the dashboard for Graffiti showing post views and popular postings. (That's not my site theme)
While the product is 1.0, it is powerful as-is and shows some real potential for future versions.
Three things I found particularly interesting in Graffiti:
- The Chalk markup language
- The .NET add-in model
- Supports importing all of my Community-Server-based blog posts from my current site
The combination of these things will allow me to tightly integrate Silverlight content into my site and migrate over to the new platform without a huge hassle. The approach of using a single product will allow me to finally combine my main site and my blog under one roof.
I'm using SQL Server 2005 as the back end for my site, but Graffiti supports the cross-platform portable and x-copy deployable VistaDB product out of the box. BTW, Graffiti also works under Mono :)
Disclosure: After I had made my decision to use this product, I approached Telligent and received an upgrade from the free version for no cost due to my MVP status. There is a free version which doesn't have the same reporting, but supports just about everything else you need.
I'm looking forward to rolling this out. When it gets a little closer to release, I'll post the URL and invite you all for feedback on the new site.
For those of you accessing my site via the RSS feed, the switchover to FeedBurner means you won't have to change a thing.
For all of you attending tomorrow's CMAP code camp, here's a sneak peek at what I'll be building in my 10:30 Silverlight 2 and Microsoft Expression session. The session is targeted towards developers, but anyone with an interest in Silverlight or Expression is welcome and encouraged to attend
The application has a server piece (the windows forms app) and, in this instance, two Silverlight clients in a chat, actually talking to each other over sockets.
Expression Design
Expression Blend
- Designing the overall UI
- Creating interesting and easy animations to make the bubbles pop up and fade away
Visual Studio 2008
- Wiring it all up and just a little bit of sockets grunge for good measure.
The session is all demo and code. You'll leave there with an understanding of how the tools work together, how to do some basic animation in Blend, how to create shapes and glass effects in design, and how to build a Silverlight 2 application.
Source code will be available some time after the code camp.
Hope to see you there!
After trying to work for months as a normal user on my Vista Ultimate install at home, I finally got tired of the problems and decided to run as an administrator like I did in previous operating systems. I gave it a good go, but have just found that environment unsuitable for a developer. Main issues:
- UAC prompt every time you install something. Annoying, but not fatal.
- Apps that for some reason don't work with UAC and just silently fail their install. If you then run them as admin, they put junk in the admin profile instead of your local profile. This was really really annoying, almost fatal.
- Getting a UAC prompt because the system confuses a locked/in-use file with one you don't have permissions to. I'd type in the id and password and then get an "access denied". This was super annoying and happened more often than you might think.
The combination of those things was all fatal to me. Back to running as a local admin. I applaud Microsoft for making the operating system more secure for the majority of users, but again lament ignoring developers. I've always thought that Microsoft should have a few install options for the OS:
- Typical User - Keep things fairly tight by default
- Corporate User Install - Controlled by IT (IT shops already do this, so this is fine)
- Developer
Of course, there are others, but the dev install would open up the OS a bit more, install a bunch of utilities and overall just eliminate all the stuff that most developers have to beg their IT department to do. Having that option would lend some credence to what those folks ask for.
Luckily at AIS we're all local admins on our laptops and have pretty much free reign over what we do on them, but I've been in lots of places where the developers work in essentially the same configuration as end users and suffer huge productivity hits, especially when they do dumb things like make it so devs can't access blogs or google newsgroups (ran into both at one particularly tightly-controlled site)
Sure, there's something to be said for developing in the target environment, but I think there's more to be said for developing in a power user environment and doing frequent (daily build) testing in the target environment. That's much more valuable and repeatable, it makes the developers more productive, and just makes more sense.
A quick reminder that the CMAP Code Camp is coming up quick!

I have a morning session where I'll build out a small Silverlight 2 application using Microsoft Expression Design, Expression Blend, and Visual Studio 2008. Almost all live demo, with only a slide or two at most. I really think you'll enjoy it.
Hope to see you there on April 12, 2008!
Loyola College Graduate Center - Columbia Campus
8890 McGaw Road
Columbia, MD 21045
USA
Register here.
Effective immediately, I am moving the RSS feed for this blog over to FeedBurner. The new URL for my feed is:
http://feeds.feedburner.com/PeteBrown
Most decent feedreaders should redirect to that and update the feed URL. If they don't, please plug the new URL in there.
I plan to migrate to a new blogging platform sometime in the near future (I'm considering several right now including SharePoint Community Kit Enhanced Blog Edition and BlogEngine.NET. Subscribing to my feed via the FeedBurner link above will insulate you from any such changes, no matter how often I make them.
If you are interested in subscribing to just the Silverlight content in this blog, the new RSS feed URL is:
http://feeds.feedburner.com/PeteBrown-Silverlight
Unfortuntately, one of Community Server's many limitations (at least the old version I am currently running) is the inability to support category RSS feeds through an external service like feedburner, so I cannot automatically change those feeds.
This is a one-time change (assuming FeedBurner doesn't tank or munge its service).
If anyone was actually using the Atom feed, email me using the contact form on my blog.
Everyone loves to hate Internet Explorer. Microsoft was originally late to the browser game, but eventually won out over other browsers. Think of that what you may, but I have to admit that the competition at the time was made up of some pretty crappy browsers. It wasn't until the battle was pretty much lost that the alternatives started getting interesting.
The IE folks sat on the browser for a while giving time for a real competitor: FireFox to come into being. FireFox is a pretty good browser and is very developer-friendly. It's far from perfect though.
That all said, someone needs to update their site code and FUD text. It doesn't even take into account advancements in IE7, which has been out for some time. I use Firefox as well, but not as my default browser and crap like what you see below just gets under my skin.
Part of being a good citizen site on the net is respecting the user's choice in browser: that means supporting IE, FireFox and Safari (and of course Opera and other common browsers), but it also means not doing obnoxious things like popping up "your browser sucks" messages on the page and forcing an extra navigation step because you have some sort of an agenda.

After all that, the site works just fine in IE7 even though it is pretty butt-ugly in any browser :)
A while back, I showed how to vectorize "drop shadows" in Expression Design. It wasn't perfect (especially at the start and stop points of the line), but it was quick, easy, and didn't require any additional png files.
Since then, Expression Design 2 has been released in Beta form, and the Expression Design team dropped the ability to vectorize the brush strokes. From speaking with them, I understand and agree with their prioritization of other features, but it is still a bummer to see a potentially useful feature go away.
I need basic rectangular shadows on a project I'm working on. I didn't want to resort to using 8 png files to cover the whole rectangle so I decided to work up a quick way to handle shadows in xaml.
First, I put together a simple linear shadow, which you can see to the left. I have included the xaml for that below.
The approach is really simple: draw a bunch of adjacent lines with diminishing opacity. You can play with the colors and the opacity to get the effect you are looking for.
Xaml for a Simple Line Shadow
<Canvas>
<Line Canvas.Left="0" Canvas.Top="0"
X1="250" X2="250" Y1="10" Y2="200"
Stroke="Black" Opacity="0.50" StrokeThickness="1"/>
<Line Canvas.Left="0" Canvas.Top="0"
X1="251" X2="251" Y1="10" Y2="200"
Stroke="Black" Opacity="0.40" StrokeThickness="1"/>
<Line Canvas.Left="0" Canvas.Top="0"
X1="252" X2="252" Y1="10" Y2="200"
Stroke="Black" Opacity="0.20" StrokeThickness="1"/>
<Line Canvas.Left="0" Canvas.Top="0"
X1="253" X2="253" Y1="10" Y2="200"
Stroke="Black" Opacity="0.10" StrokeThickness="1"/>
</Canvas>
I was reasonably pleased with the result with the single line test, given the minimal effort it took, so I took a stab at rectangular shadows. You can see the result of that to the left.
I happened to use borders. You could easily use a Rectangle, border just happened to be what I was messing around with at the time. In many cases, a Rectangle or other shape will be more appropriate.
The result here looks fine too, as long as you don't scaletransform it. When you apply a transform, you will start to see banding due to the lines. In those cases, you might actually get better results just by biting the bullet and going with the png method, allowing Silverlight to scale and blur the pixels.
Note that you'll need to change the radius for each, as well as decreasing the x and y positions by 1 and increasing the width and height by 2.
Xaml for the Rectangle Shadow
<Canvas>
<Border CornerRadius="10.0" Canvas.Left="4" Canvas.Top="4"
Width="100" Height="150" BorderThickness="1"
BorderBrush="Black" Opacity="0.50" />
<Border CornerRadius="11" Canvas.Left="3" Canvas.Top="3"
Width="102" Height="152" BorderThickness="1"
BorderBrush="Black" Opacity="0.40" />
<Border CornerRadius="12" Canvas.Left="2" Canvas.Top="2"
Width="104" Height="154" BorderThickness="1"
BorderBrush="Black" Opacity="0.20" />
<Border CornerRadius="13" Canvas.Left="1" Canvas.Top="1"
Width="106" Height="156" BorderThickness="1"
BorderBrush="Black" Opacity="0.10" />
</Canvas>If you have an arbitrary shape, defined by a path, it will be more challenging to create a workable drop shadow.
You can take the concepts here and get even better results by playing with the thickness and positions (fractional positions and additional lines should give a smoother line when transformed).
Ideally Silverlight will gain the effects capability of WPF and/or Flash in the future. Until then, we'll just have to fake it :)
Please join me in congratulating fellow AIS'er and and MVP Frank La Vigne for being renewed as Microsoft MVP for 2008!
Frank is a Tablet PC MVP, but he has also been doing a lot of Silverlight and WPF work lately. Frank set up the Silverlight DevCamp DC last year, and has been instrumental in planning and speaking at events since then. He's also working on a very cool WPF app for a i'd-have-to-shoot-you-if-I-told-you customer of AIS.
Congrats!
The Microsoft Health and Life Sciences Evangelism Team have put together a great free event in NJ with Silverlight, SQL Server, Surface, Silverlight Mobile, WPF, AJAX and lots more.
April 22 - April 24 2008
Sheraton Atlantic City Convention Center Hotel
Two Miss America Way
Atlantic City New Jersey 08401
United States
Solutions Focused
· Health 2.0 – Health & Life Sciences version of web 2.0
· Connected Industry Framework (CIF) – “SOA enablement for Health & Life Sciences”
· Office Business Applications for Life Sciences – “solutions for Life Sciences”· Consumer Enablement Reference Architecture(CERA) – “empowering consumers in the new Healthcare age”
· Consumer Enablement Reference Architecture(CERA) – “empowering consumers in the new Healthcare age”
· Patient Safety Screening Tool (PSST) – “saving patient lives through proactive measures” Deep Technical Content
Confirmed Technical Sessions include:
· Programming Microsoft Silverlight 2.0
· Building Secure ASP.NET AJAX Applications
· ASP.NET AJAX Design & Development Patterns
· SQL Server Data Services – scalable, easily programmable and highly available utility-based data store
· Building Enterprise Office Business Application Mashups
· Windows Presentation Foundation for Information and Data Visualization
· Managing the Application Lifecycle with Visual Studio Team System
· Presence and speech enabling your applications with Microsoft Unified Communications
· Architecting for High Performance and Multicore with Microsoft HPC and the .NET Parallel Framework
· Maximizing Data Value through Design of Charts and Visualization
You can find more information Allan's blog here. The session list and registration link are available here.
If you are looking for some great Silverlight 2 charts and graphs for data presentation (not interactivity at this point), check out what the people at
VISIfire have come up with. Besides being a great example of what one can do with vector drawing, and a quick way to get very good looking charts and graphs in your app, you get all the source code (GPL) for each so you can easily create your own or just learn from what they have done. Nice!
The webcast recording is now online. To view the recording, registe