First time here? Check out the site's "greatest hits" or read a post from the archives. Feel free to leave a comment or ask a question, and consider subscribing to the latest posts via RSS or e-mail. Thanks for visiting!

NOTE: If you haven't read the first post in this series, I would encourage you do to that first, or check out the BabySmash category. Also check out http://windowsclient.net/ for more developer info on WPF.

BACKGROUND: This is one of a series of posts on learning WPF. I wrote an application for my 2 year old using WPF, but as I'm a Win32-minded programmer, my working app is full of Win32-isms. It's not a good example of a WPF application even though it uses the technology. I'm calling on community (that's you, Dear Reader) to blog about your solutions to different (horrible) selections of my code. You can get the code http://www.codeplex.com/babysmash. Post your solutions on your blog, in the comments, or in the Feedback and we'll all learn WPF together. Pick a single line, a section, or subsystem or the whole app!

Someone wanted the BabySmash Window to have the option to be transparent. I figured, hey, WPF must be good at that, transparency at all. I bet it'll be like one line of code.

I went into my MainWindow.xaml and added these attributes:

Background="Transparent" AllowsTransparency="True" WindowStyle="None" 

Bam! Right? Well, kind of. This made the Window Transparent, but "hollow" in that I couldn't click on it. It was totally invisble, except for my little bit of text at the top. I could "click through" the application to the desktop below.

image

Well, here's why, and if I'd read 4 chapters into Chris Sell's book, I'd have figured this out. ;)

Per Dwayne Need on the WPF Team:

"Windows treats fully transparent layered-windows windows as hollow."

This was interesting because everywhere else in WPF if you have a Brush that is null, that's "hollow" and Transparent is solid. Again, Dwayne:

"This is because a layered window is represented to the OS as a bitmap, so all it can do is look at the pixel values.  It [Windows] cannot differentiate between null and Transparent."

Ah, makes sense. This is where WPF meets the rest of Windows. Ok, but I have complete control over my Brushes and their colors. I can make a Brush that is not just #000000 (Black) but also #01000000 (really really transparent black. Like 1/255th transparent). You've got not just RGB, you've got an Alpha Channel PLUS RGB.

Now if I set my Window's background to this Brush:

new SolidColorBrush(Color.FromArgb(1,0,0,0))

I get the look of transparency, except the Window is still there and I can click on it.

"Your almost-transparent brush fails the Windows transparency test, so windows delivers events to it. If something is 100% transparent then hit testing is bypassed.  If you want transparency and hit testing, define a color with minimal alpha just as you have done.

This was an interesting edge class where WPF's definition of Transparent didn't quite line up with Window's definition.

Once you've created a Window that is transparent like my funky full-screen one,,,

MainWindow m = new MainWindow(this)
{
WindowStartupLocation = WindowStartupLocation.Manual,
Left = s.WorkingArea.Left,
Top = s.WorkingArea.Top,
Width = s.WorkingArea.Width,
Height = s.WorkingArea.Height,
WindowStyle = WindowStyle.None,
Topmost = true,
AllowsTransparency = Settings.Default.TransparentBackground,
Background = (Settings.Default.TransparentBackground ? new SolidColorBrush(Color.FromArgb(1,0,0,0)) : Brushes.WhiteSmoke)
};

...you can't change the Transparency after you've shown it...or else...

image

Chris Sells suggested I set my Window to AllowsTransparency = True all the time, then make a Canvas over the top of it that had an opaque Brush with color and transparency I could change as I liked as it'd be "inside" WPF world and not have to deal with any underlying limitations in Win32.

For now, my not-quite-transparent brush got me the feature I wanted - BabySmash over an existing desktop.

image

Cool.

Technorati Tags: ,,


NOTE: If you haven't read the first post in this series, I would encourage you do to that first, or check out the BabySmash category. Also check out http://windowsclient.net/ for more developer info on WPF.

BACKGROUND: This is one of a series of posts on learning WPF. I wrote an application for my 2 year old using WPF, but as I'm a Win32-minded programmer, my working app is full of Win32-isms. It's not a good example of a WPF application even though it uses the technology. I'm calling on community (that's you, Dear Reader) to blog about your solutions to different (horrible) selections of my code. You can get the code http://www.codeplex.com/babysmash. Post your solutions on your blog, in the comments, or in the Feedback and we'll all learn WPF together. Pick a single line, a section, or subsystem or the whole app!

image I hung out with Chris Sells at the Mall Food Court today. He had trouble finding a parking spot and I felt bad. But I didn't REALLY start feeling bad until I started showing him the code for BabySmash.

He had a number of ideas for ways to make BabySmash better, but what was interesting was that he was using his own book as reference. He'd say, "oh, we did that in Chapter 4" and "ya, that does suck, check out this call out where I explain why." After this happened about four or five times he said (I think in jest, but you can never tell with famous dudes. ;) )

"Did you invite me here to read my book to you?"

After I picked my ego off the ground, unfolded it, dusted it off, and smoothed it out, I said, "I don't think so."

Chris had a really good point. It turned out that even though I have a three WPF books at my house, I haven't read them all deeply and thoughtfully. I hadn't even made it though the first few chapters. Mostly I skipped around, looking for answers to my specific questions.

Through my questioning, Chris noticed that I had some fundamental misunderstandings about some the basics of WPF. Things I thought worked one way, worked another or in reverse. Some concepts that were WPF 101 I had overlooked completely because I hadn't least made it through ~5 chapters and cemented the fundamentals.

I am not saying that we need to read every book all the way through, but I did learn a useful lesson. Don't assume you know how it works. Just a few hours of covering the fundamentals would have saved me a lot of time.

In the last post I said I was starting to grok WPF. Looks like less than I thought. I had left pretty significant gaps in my understanding by skipping around and assuming "oh, this works like that."  Those gaps in my knowledge led to some interesting directions in BabySmash. I'll post about some of those things I learned from Chris soon, but suffice it to say, I completely misunderstood how events moved around a WPF application.

Thanks Chris for setting me straight! Sorry about the parking!

OK, page one, "Hello, WPF."



NOTE: If you haven't read the first post in this series, I would encourage you do to that first, or check out the BabySmash category. Also check out http://windowsclient.net/ for more developer info on WPF.

BACKGROUND: This is one of a series of posts on learning WPF. I wrote an application for my 2 year old using WPF, but as I'm a Win32-minded programmer, my working app is full of Win32-isms. It's not a good example of a WPF application even though it uses the technology. I'm calling on community (that's you, Dear Reader) to blog about your solutions to different (horrible) selections of my code. You can get the code http://www.codeplex.com/babysmash. Post your solutions on your blog, in the comments, or in the Issue Tracker and we'll all learn WPF together. Pick a single line, a section, or subsystem or the whole app!

When I decided I was running out of ideas for BabySmash! I decided that I needed to get some customer feedback. The babies had less to say that expected, but there are many videos of babies testing the application popping up on Flickr and YouTube, so I'll call that End User Testing.

I found a site called UserVoice.com (another similar one is GetSatisfaction.com) that is basically a hosted instant customer feedback site. Poof. UserVoice.com even supports a few widgets via Javascript like this one for embedding on your site.

It also supports DNS CName aliasing, so http://feedback.babysmash.com looks like it's hosted by me at http://www.babysmash.com, but instead it's at UserVoice. It's really professional and takes literally minutes. I had the whole thing installed an integrated in under 15 minutes, including color customization and logo.

After I put the site up and inserted links to BabySmash Feedback on the site, there were two ideas that didn't get many votes but had great potential and I figured would be fun to do. One person suggested using Wingdigs (the silly font) to use letter keystrokes to show the fun pictures embedded in the font, while the other suggestion was just to allow a custom font.

When I make the Letters, I create a single object of FormattedText and had hardcoded "Arial," then I call BuildGeometry() on that which basically creates a Path or Outline of the letter that I can mess with. I fill it, and outline it and sent it on its way. I hadn't even given alternative fonts a second thought.

private static Geometry MakeCharacterGeometry(string t)
{
var fText = new FormattedText(
t,
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface(
new FontFamily(Properties.Settings.Default.FontFamily),
FontStyles.Normal,
FontWeights.Heavy,
FontStretches.Normal),
300,
Brushes.Black
);
return fText.BuildGeometry(new Point(0, 0)).GetAsFrozen() as Geometry;
}

So armed with this idea, I added FontFamily as an option in Visual Studio Settings for this project. Remember that I refactored the Options Dialog a few weeks back using Jason Kemp's code. This made it easy to just add one additional ComboBox. I'm getting good enough that I added the XAML in the Text Editor pane in Visual Studio rather than the designer.

image

I figured, since this WPF, can't I make that ComboBox more interesting than just a bunch of strings? Why not have the FontNames show up in the style of the Font like in Word? Well, System.Windows.Media.Fonts.SystemFontFamilies has the list of the fonts on the machine. I searched around and found part of what I needed at Norbert Eder's WPF blog. (BTW, congrats on being a newly minted MVP!)

<Window.Resources>
<local:Settings x:Key="settings" />
<CollectionViewSource Source="{Binding Source={x:Static Fonts.SystemFontFamilies}}" x:Key="myFonts"/>
</Window.Resources>

I can make a CollectionViewSource and make it a resource that is available to the Window, as seen above. The source is the collection of FontFamilies. Next, I make a regular ComboBox, which usually looks like this if you are just holding strings:

<Label Height="23" Grid.Row="2" Margin="10">Cursor</Label>
<ComboBox
SelectedValue="{Binding Path=Default.CursorType}"
SelectedValuePath="Content" Grid.Row="2" Height="23" Margin="70,10,7,0" Grid.ColumnSpan="2" VerticalAlignment="Top">
<ComboBoxItem>Hand</ComboBoxItem>
<ComboBoxItem>Arrow</ComboBoxItem>
</ComboBox>
But in mine, I'm going to bind the ItemsSource to the list of Fonts from the Resources above. I'll say that the ItemsPanel will be a VirtualizingStackPanel which is amazing. You know when you have a long list of potentially expensive-to-show stuff? The VirtualizingStackPanel knows it's expensive takes care of doing the minimal amount of work it takes to show just those items that are visible. This makes rendering hundreds of fonts way faster.
<ComboBox x:Name="FontChooser" Grid.Row="3" Margin="70,10,7,0" 
ItemsSource="{Binding Source={StaticResource myFonts}}"
SelectedValue="{Binding Path=Default.FontFamily}" SelectedValuePath="Source" Height="23" VerticalAlignment="Top" Grid.ColumnSpan="2">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontFamily="{Binding}" Height="20"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

The Data Template is what each item looks like, which is just the name of the font and setting the FontFamily to that item's FontFamily! Hard to write until you've done it once, then you start thinking of other cool stuff you can do with this knowledge elsewhere in your app.

The one thing that it flummox me for a half-hour was that I was binding the ComboBox to the list of Fonts from my Resources, but I wanted the SelectedValue (the item that is selected in the ComboBox) to be bound like all the other controls in my options dialog, to my application's Settings. That's where these attributes came in:

SelectedValue="{Binding Path=Default.FontFamily}" SelectedValuePath="Source" 

There the SelectedValue the FontFamily string from my Settings class (just like the Default.CursorType and others in the dialog) and the SelectedValuePath shows how to dig into that value. In this case, the Source property had the name (string) of the FontFamily.

The result looks like this:

 Baby Smash! - Options

I'm starting to "grok" WPF more each evening I code on BabySmash. I know I'm still just barely scratching the surface. I'm looking forward to implementing (with your help) more of the BabySmash Feedback Items.



I wanted a custom cursor for BabySmash! My son was having trouble associating the mouse cursor on the screen and the movement of the mouse. Clearly a shiny new Kids Cursor was in order.

I went into Expression Blend and drew this hand cursor. I drew it with the spliney-liney pully-thing-tool. (That's the official name for it, I'm sure.

image

I was feeling pretty good about this cursor. It had a gradient and everything. I put it up, but mentioned to Felix The Designer that maybe he wanted to have a go at making a cursor. Seven minutes later I received this. If you want to understand what real design talent is like, read about Felix's thought process as he redesigned the Mix site.

image

At this point I declared, in the style of American Comedian Larry Miller:

"The difference between a Designer and Developer, when it comes to design skills, is the difference between shooting a bullet and throwing it." - Scott Hanselman with apologies to Larry Miller

More on the Designer/Developer relationship later, but for now, thanks to Felix and Conchango, BabySmash is looking pretty professional, IMHO.

image

Developer != Designer. Sigh.



My one-hundred-and-twentyfirst podcast is up.image In this episode, I talk to Rick Barraza, an Experience Architect from Cynergy with a background in Flash, and Bryan Perfetto, a Developer from Inxile writing his first Silverlight application. We chat about how and why they ported the popular Flash Game LineRider.com to Silverlight 2.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

If you have trouble downloading, or your download is slow, do try the torrent with µtorrent or another BitTorrent Downloader.

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Telerik's new stuff is pretty sweet, check out the ONLINE DEMO of their new ASP.NET AJAX suite. RadGrid handles sorting, filtering, and paging of hundreds of thousands of records in milliseconds, and the RadEditor loads up to 4 times faster and the navigation controls now support binding to web services on the client.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?



ASP.NET MVC Preview 4 is up on CodePlex. The Gu has all the exquisite Gu-Like Detail on his blog. Phil Haack has some notes on this release on his blog.

If you take a look at the generated "changes" document, it shows a bunch of new stuff like AjaxHelpers and AjaxExtensions that set the stage for some interesting things the community could do with ASP.NET MVC and Ajax. I'd like to see some JQuery love in there, maybe with some MVCContrib as they've been quiet lately.

Using the new Preview 4 bits, here's what I was able to get running in just a few minutes.

Given a ViewPage that has a TextBox and a Button on it, when I click the button (and submit the form) I'll call back to the server and get some text that should then go in the div next to the button.

mvcpreview4ajax

The View looks like:

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<p>
<%using (Ajax.Form("ExamineTextBox", new AjaxOptions { UpdateTargetId = "result" }))
{ %>
<%= Html.TextBox("textBox1")%>
<input type="submit" value="Button"/>
<span id="result"/>
<% } %>
</p>
</asp:Content>

Notice the Ajax.Form helper and the UpdateTargetID that refers to the span. There's more AjaxOptions in there to explore as well, that we'll see in a second. The controller action looks like this:

public class HomeController : Controller
{
public string ExamineTextBox(string textBox1)
{
if (textBox1 != "Initial Data")
{
return "This text is MVC different from before!";
}
return String.Empty;
}
}

Notice that the return method of the ExamineTextBox isn't an ActionResult, it's a string. In fact, the string result is being wrapped for you into a ContentResult. You could certainly make a ContentResult yourself, but this makes for a nicer looking method signature.

The result of that method is returned via the AJAX call, then put into that span via magic and pixie dust. Actually, the request looks like this:

POST /Home/ExamineTextBox HTTP/1.1
Referer: http://localhost.:45210/Home
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Accept-Encoding: gzip, deflate
Host: localhost.:45210
Content-Length: 28
Connection: Keep-Alive
Pragma: no-cache

textBox1=dude&__MVCAJAX=true

and the Response like this:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/9.0.0.0
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 39
Connection: Close

This text is MVC different from before!

And that UpdateTargetID (the span) mentioned in the Ajax Form helper above? That's swapped in via the magic in MicrosoftMvcAjax.debug.js. There are options for before, after and replace.

// Insert the results into the target element
if (targetElement) {
switch (insertionMode) {
case Sys.Mvc.InsertionMode.Replace:
targetElement.innerHTML = executor.get_responseData();
break;
case Sys.Mvc.InsertionMode.InsertBefore:
targetElement.innerHTML = executor.get_responseData() + targetElement.innerHTML;
break;
case Sys.Mvc.InsertionMode.InsertAfter:
targetElement.innerHTML = targetElement.innerHTML + executor.get_responseData();
break;
}
}

Note that I had to manually (for now) add the JavaScript libraries, so I put them in my Site.Master View.

<script src="/Content/MicrosoftAjax.debug.js" type="text/javascript"></script>
<script src="/Content/MicrosoftMvcAjax.debug.js" type="text/javascript"></script>

Also, notice that the MicrosoftMvcAjax.js is new and it's in your /Content folder if you make a new MVC Application. Congrats to Phil and Eilon and the team for this release!

Related Links



Bil Simser has just done the .NET Community a huge solid. Bil has dug up and re-released Terrarium to CodePlex wtih the intent to update it to use new language features and new usability features like ClickOnce.

If you're newish to the .NET Community (<3-5 years?) you might not have heard of Terrarium. There was a time when it was the tool for getting newbies excited about learning .NET. I showed dozens of high-school and college students how to program using Terrarium. Back at my last company one of our engineers did brown bag lunches on good bug design and ran a Terrarium Server internally.

terriarium

Terrarium hasn't been even looked at by the Microsoft SDK team in two years, as live happens, you know. Bil hunted them down, did a bunch of paperwork and it's back. You can check out the source or download the release.

You can run it alone, just a world in a box, or you can hook it up to a server and that's where it gets interesting, as your bugs all live in a connected world.

Your animals have Idle (event-based) loops that you can react to, and who amongst us hasn't wanted to write these lines of code at least once?

// Reproduce as often as possible 
if (CanReproduce)
BeginReproduction(null);

Now you have the chance.

A great lunchtime project is to get a bunch of the nerds from your company in a room, teach them Terrarium and have a battle!

Personally, I'm a lover, not a fighter, so I run away when attacked.

private void MyAnimal_Attacked(object sender, AttackedEventArgs e)
{
if (e.Attacker.IsAlive)
{
AnimalState TheAttacker = e.Attacker;

BeginDefending(TheAttacker); //defend against the attacker
WriteTrace("Run away to some random point");

int X = OrganismRandom.Next(0, WorldWidth - 1);
int Y = OrganismRandom.Next(0, WorldHeight - 1);

BeginMoving(new MovementVector(new Point(X, Y), 10));
}
}

Go check out the release of Terrarium and download the app, SDK and server. There will be more to come on Bil's Blog, I'm sure. He'll also be running a public Terrarium Server. It's exciting to see this blast from the past. Now I think it's time for me to visit a local High School Computer Science class again some lunchtime...

One of the things I think will be interesting to see, is if folks come up with better patterns for managing state within these animals. Many Terrarium animals end up with Idle loops that look like Arrow Code.

if
if
if
if
do something
endif
endif
endif
endif

This isn't nice to look at, and it would promote bad habits if it was the first kind of code someone new to programming ever saw.

The world has changed since this was released in 2002. The race is on and now I ask:

  • Who will write the first aesthetically pleasing (from a code perspective) Terrarium Animal?
  • The first F# Terrarium animal?
  • The first Ruby (DLR) Terrarium animal?
  • Boo? Nemerle? IronPython?

Enjoy!

UPDATE: I've got this running on my XP machine and my XP VMs but because of missing DirectX 6/7 DLLs I can't get it running under Vista. Possible workaround in the comments below. It'll likely be faster to just recompile it. I'll talk to Bil and see what's up.

 

Related Links



image I really like the IIS7 team at Microsoft. They're cool people, but the what I like is that IIS7 is so freaking modular (I've talked about this at conferences before when showing how to use PHP and Ruby under IIS7 using FastCGI) that the group keeps bringing out new functionality as "OOB" or Out Of Band releases.

Bill Staples as a good post on how IIS7 ships software now. There's a big list of all the Release to Web (RTW) modules for IIS7. I demo'ed a the Bit Rate Throttler at TechEd and talked about it in a post on"Squeezing the most out of IIS7 Media Bit Rate Throttling which can help people save bandwidth money while hosting downloadable files/media.

This week the IIS7 team put out three new preview releases for download.

  • IIS7 PowerShell Provider CTP2
    • This provider marries the two technologies and makes administrating IIS7 feel more natural to PowerShell folks. To put it bluntly, you can "cd" into iis:\ as if it were a drive, the type "dir" to see your websites. Drink that in. It's the bomb. I loves me some Powershell.
  • URL Rewrite Module CTP1
    • Just what it sounds like. Unlike ISAPI_Rewrite (which I love) this is an HTTP Module rather than an ISAPI Filter, and it includes an integrated UI for management within the IIS Manager.
  • OSIApplication Request Routing CTP1
    • This is the real dark-horse release. It's got that bland "huh?" name that might cause you to just blow it off or ignore it in the middle of these three modules' release. However, it's deceptively powerful and worth checking out.
      • It requires the URL Rewrite Module above, and hugely builds on its functionality. If you get an error while installing ARR, you need to go install the URL Rewrite Module first.
      • IMPORTANT NOTE: You have to run the MSI from an Administrator Command Prompt. Just running the MSI by double clicking doesn't work. This is a known bug in this CTP. Bummer.

Application Request Routing is interesting. At first I thought it was like NLB (Network Load Balancing), that feature of NT 4.0 that used to be called "Wolfpack." I figured that the great Load Balancing Wars of the '90s were won, and the winner was hardware. I've used Cisco LocalDirector and F5's BigIP in my previous jobs.

ARR is basically a proxy module with load balancing capability that does its routing at Layer 7, rather than Layer 4. That means you make decisions at the HTTP level rather than the IP level. It sits on top of the URL rewrite module, so you can write routing or load balancing rules that can key off of HTTP Headers or Server Vars. You can do Client Affinity via cookie to differentiate between clients behind NAT.  These rules mean it could compliment a system that has an existing hardware load balancer.

If you're familiar with Apache, IIS7's ARR Module kind of combines the functionality you'd find in modproxy, modloadbalance, modproxyhttp along with some other goodness.

It's also a nice reverse proxy if you've ever wanted to do have a smarter IIS7 app router in your home to sit on the outside of your network and route traffic to machines or services inside.

For example, this screenshot shows a routing condition where we want to route folks who have .NET 3.5 on their systems to a separate server. Perhaps a beta site, or a site that has ClickOnce apps or some different functionality. It's totally up to you. You could route folks with certain cookie values, browsers, or  based on path requested.

image

If we had 3 machines in the farm, one IIS7+ARR for routing in front and two other IIS7 machines behind it, I could write a rule that said "don't route requests for images." In this example, I'll have the /images folder served by the ARR machine up front instead.

image

It also has Health Monitoring to check on boxes being down, and you can decide what "healthy" means to you.

ARR is a free download and it plus into IIS7 Manager using the new UI extensibility stuff in IIS7, so it just looks like part of IIS and is managed the same way you manage everything else.

Download

Check 'em out. I'm looking into how I can use ARR to expose my internal Subversion server in a more secure and easily configurable way.

Related Links



iStock_000002684567XSmall Are you in King County/Seattle/Redmond/Bellevue Washington and surrounding areas? Are you a huge nerd? Perhaps a geek? No? Maybe a spaz, dork, dweeb or wonk. Maybe you're in town for an SDR (Software Design Review) or the ASPInsiders meeting. Quite possibly you're just a normal person.

Regardless, why not join us for some Mall Food at the Crossroads Bellevue Mall Food Court on Tuesday, July 22nd around 6:30pm?

Here's some links to help you remember and add this to your calendar, or head over to http://nerddinner.events.live.com. There's photos of previous Nerd Dinners up on Flickr thanks to Orcmid.

Add to your calendar

I hope to see you there!

NOTE: Even though I told Live Events this was an Open To Anyone Event, it seems to want invitations. Just leave a comment here and show up on July 22nd at 6:30pm! Everyone is welcome, Microsoft employee or not. The more the merrier.



Contact

Sponsors

On this page...

Tags

Calendar

<July 2008>
SunMonTueWedThuFriSat
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

Archives

Google Ads