<body>

Blankenthoughts

These are my thoughts. Nothing more.

Day of .NET Events Near You! (and details about poker this weekend)

Monday, April 14, 2008

There are three opportunities for you to get your "learn on," for FREE, in the next month.

April 19 - Central Ohio Day of .NET - Wilmington, OH
Registration has already maxed out for this one at 250 people! A great number for the third year of this event! They will have 27 different sessions to choose from, and on top of being a great day of learning, I am putting together a little event afterwards for anyone that is sticking around at the Roberts Centre that night. More on that at the end of this post.


May 10 - West Michigan Day of .NET - Grand Rapids, MI
The second year for this event, in Grand Rapids, MI. The day will focus on the future of .NET an cover all the world-class technology Microsoft has or will release this year. In addition, the day will consist of breakout sessions with breakfast and lunch included!



May 17 - Cleveland Day of .NET - Cleveland, OH
Cleveland Day of .NET is a free one day conference targeted at developers using the Microsoft .NET platform. It is a collaborative effort among the various local user groups and is open to all developers, local or otherwise. This event is occurring on Saturday, May 17, 2008 from 8:00 AM to 5:30 PM.

There will be numerous sessions to choose from covering a variety of topics. The exact session list will be coming in a few weeks but you can look forward to topics such as:

ASP.NET
Silverlight
DLR / IronRuby / IronPython
SharePoint / MOSS
SQL Server 2008
... many more





Poker .NET (Newbies Encouraged to Try)
I am hosting a Texas Hold'Em Poker Tournament for the first 20 responding attendees of the Central Ohio Day of .NET. It will be held at the Robert Centre, the evening of the CODODN. I've reserved a "parlor suite" that will accomodate us with a full (unstocked) wetbar, refrigerator, and furniture for hanging out. You are welcome to bring anything you'd like to eat and drink while you're there.

We will get started with the tournament at 8:00 PM...plenty of time to hang out with folks after the CODODN and still have some fun in the evening playing cards with your geek friends. The hotel room also has accomodations for sleeping, so if you were looking for a place to crash after the event, I can provide that for a few travelers as well.

The buy-in will be $20, and all of the rules, etc. will be provided when you arrive. Expect your standard Hold'em rules to apply. Please contact me directly at jeffrey.blankenburg@microsoft.com to "register."

Labels: , , , , , , ,

posted by Jeff Blankenburg, 2:17 PM | link | 0 comments |

Left Outer Join in LINQ

Thursday, April 10, 2008

So, you're gonna notice that I'm just gonna start throwing random code at you for the next few weeks. I'm building an application in Silverlight 2, and there's going to be many lessons for me to learn along the way.

Those lessons that I can turn into a tutorial will become posts, and today is the second one. (If you're just joining us, the first one was Simple Scaled Resizing In Silverlight 2).

So after I got my application resizing nicely, I wanted to start working with my legacy database. We'll cover how I created my WCF Service in a future post, but for today, I want to talk about how to do a LEFT OUTER JOIN statement in LINQ. It's not necessarily obvious.

First things first, let's look at my data structure.



Ideally, I want to be able to pull out a list of teams that meet a certain criteria, and also retrieve their information for this year (2008 in this example) if it even exists, which it may not. The standard join statement I would write for this would look like:



But, because there is actually NO data (I haven't populated it yet) in the team_annual_data table, my query returns 0 rows, because, much like an INNER JOIN in T-SQL, there wasn't matching data on each side of the query, so there weren't any qualifying rows to return. But I want all of the rows from the left side, and if there's data on the right, let's have that too, but it's not required. To do that, we need to structure our join statement a little differently:



The primary difference is the "join into" statement. That creates the "LEFT OUTER JOIN" in the resulting T-SQL statement, allowing me to retrieve my "maybe it does, maybe it doesn't" set of data.

Labels: , ,

posted by Jeff Blankenburg, 8:26 PM | link | 2 comments |

How About Some Code? Simple Scaled Resizing In Silverlight 2 Beta 1

Saturday, April 05, 2008

I've been talking technology for a while here, but it's about time I start adding some value. I already mentioned the JUXtapose blog, so get over there for podcasts on User Experience and the technologies I use to make my UX and UI better.

Today, I want to talk about Silverlight 2 (Beta 1). One of the things that always frustrated me when creating a new application is that nobody ever wrote a good example of how to get my Silverlight application to scale with the random sizes of my user's browsers. As long as I stay vector based, this application should look the same at 640x480 and 1280x1024. And if it makes sense to have it on a mobile phone, then let's use the same application there too.

Today, my friends, I've got the simple steps you need to make your Silverlight 2 application scale effectively. I'll start this tutorial after you've created your default application (there's a great walkthrough on that here by Jesse Liberty).

I am using Visual Studio 2008, and Microsoft Silverlight Tools Beta 1 for Visual Studio 2008. My .entire solution can be downloaded here, so you can compare the changes I have made to a default project.


Step 1


If you followed the usual steps, your project should look something like mine.
Solution Explorer for this project.
We're only going to be working in two files for this: Page.xaml, and its code-behind file, Page.xaml.cs. First, let's take a look at the Page.xaml file, because more of our work will be code, not markup. Below is a shot of the entire XAML file (click to enlarge).
page.xaml contents
The only additions I have made to this file are the entire <canvas.rendertransform> section. I've also made the rootCanvas red, so that we can see it. One other thing that I have to credit Matt Casto for finding...you MUST define an initial size for your RootCanvas. Mine is 800x600, but you can use any size you'd like.


Step 2


Now we've got a little code to write, but it's honestly pretty straightforward. We've got four things to add:

  1. an event handler for when the browser is resized.

  2. a Page_Loaded method to intialize everything.

  3. a proxy method for resizing our Silverlight control initially.

  4. a Resize() method for doing the heavy lifting.


Here's a screenshot of my entire application namespace within the page.xaml.cs file (click to enlarge).
page.xaml.cs contents

First, we need to create a couple of variables. primarily, I need variables for the original height and width of my control before I get started. You'll see why in a moment, but it's basically to retain the "aspect ratio" of our control.

Second, in my "main" method, Page(), I route a new RoutedEventHandler to my Page_Loaded method when the XAML loads.

this.Loaded += new RoutedEventHandler(Page_Loaded);


Third, I have to create my Page_Loaded method. Here, I need to capture the original height and width, and I also add a new event handler to my application when the "host.content" = browser is resized. Finally, I call my Resize() method.


void Page_Loaded(object sender, RoutedEventArgs e)
{
_originalWidth = RootCanvas.Width;
_originalHeight = RootCanvas.Height;
Application.Current.Host.Content.Resized += new EventHandler(Content_Resized);
Resize();
}


Fourth, now that I have a new event handler pointing to Content_Resized(), I should probably write that method too. It just passes the call along to my Resize() method.


void Content_Resized(object sender, EventArgs e)
{
Resize();
}


Fifth and finally, I need to write my Resize() method. This is slightly more complicated than you might expect, but there's a reason. We need to capture the width and height of the new browser size. That's what currentWidth and currentHeight are for. uniformScaleAmount is what makes this complicated. We want to scale this thing uniformly, that is to say, if the application was originally 800x600, we want to keep a 4:3 ratio at all times, rather than stretching the app to fill the space allowed. Once we have determined the appropriate scale constant, we then also want to keep this app centered both vertically and horizontally in the browser as well. The last 4 lines of the code handle this, by altering the size of the overall control.


double currentWidth = Application.Current.Host.Content.ActualWidth;
double currentHeight = Application.Current.Host.Content.ActualHeight;

double uniformScaleAmount = Math.Min((currentWidth / _originalWidth), (currentHeight / _originalHeight));
RootCanvasScaleTransform.ScaleX = uniformScaleAmount;
RootCanvasScaleTransform.ScaleY = uniformScaleAmount;

double scaledWidth = Math.Min(_originalWidth * uniformScaleAmount, currentWidth);
double scaledHeight = Math.Min(_originalHeight * uniformScaleAmount, currentHeight);
RootCanvasTranslateTransform.X = (Math.Min(RootCanvas.ActualWidth, currentWidth) - scaledWidth) / 2d;
RootCanvasTranslateTransform.Y = (Math.Min(RootCanvas.ActualHeight, currentHeight) - scaledHeight) / 2d;
}


Please give this a try on your next application. You should be able to use this on any size Silverlight application, and as long as your creative assets can handle scaling to any size (read: vector), your application should look great at all sizes. Please leave me a comment if you give this a try...I want to know that I helped someone out!

Labels: , , , ,

posted by Jeff Blankenburg, 8:42 PM | link | 3 comments |