Cin-Day Nerd Dinner Reminder

This is just a quick reminder that tomorrow (April 2nd) we will be having our first Cin-Day Nerd Dinner.  If you are planning on coming, but haven’t RSVP’ed please do so here so that I can warn Dewey’s Pizza in West Chester of the raucous crowd to be expected.  Can’t wait to see everyone.

Posted 04-01-2009 by cromwellryan | no comments
Filed under:
Action(Of T) Lambdas in VB

Until VB catches up with C# in the lambda support realm, here is how you can accomplish those Moq or Rhino.Mocks style verifications in VB:

dim someSub as Action(Of double) = AddressOf mockObject.SomeSub
Rhino.Mocks.Expect.Call( someSub)

It’s very frustrating going from the full support in C# to VB, but I’m finding sufficient workaround for most items.  I shouldn’t be so hard on VB.  C# doesn’t support inline of Xml which is pretty friggin’ sweet.

Posted 03-30-2009 by cromwellryan | 1 comment(s)
Filed under:
Outlook 2007 Huge Performance Improvement

If you use Outlook 2007 go get this hotfix (download here) now.  It’s crazy faster after this update.

 

Hurry!

Cin-Day Nerd Dinner

I’m jumping on the bandwagon and you’re all invited to follow.  I’ve scheduled a Nerd Dinner at Dewey’s Pizza in West Chester on April 2nd.  It’s just off the Tylersville exit on I75. 

I’ll have both the Dayton and Cincinnati User Groups announce the event at their upcoming meetings.  Please try to RSVP so I can warn Dewey’s of the wild crowd.

Scaling ItemsControl Items for Explicit Visible Items in WPF

Another part of the overall solution we were trying to come up with in conjunction my previous post on Scrolling Multiple Content Areas, we also needed to come up with a way to only show X number of items in the visible region of an ItemsControl wrapped in a ScrollViewer.  This was more tricky than I had initially anticipated, but the solution seems to work for us and its got relatively few moving parts. 

The end result of the concept can be visualize in this Xbap example.  By moving the slider at the bottom, you effectively change the width of the ItemsControl containing the colored Ellipses.  In order to do this as a reflection of the number of items contained within, you need another IMultiValueConverter.

Here is the meat of the code for the RelativeSizeConverter I came up with:

public class RelativeSizeConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if( values.Length != 3 )
            throw new InvalidOperationException("Don't do that!");
        double containerSize = System.Convert.ToDouble(values[0]);
        int totalItems = System.Convert.ToInt32(values[1]);
        int visibleItems = System.Convert.ToInt32(values[2]);
        var visibleSubgroupSize = containerSize / visibleItems;
        return totalItems * visibleSubgroupSize;
    }
}

Basically we figure out how wide things would be if we only had the visible items and then we apply that to all the items return.  In order for this to work, there cannot be any sizing between the ItemsControl and the ScrollViewer, but its a small price to pay.  That would look odd any way in my opinion, but maybe I am simply justifying the solution!

Anyways, putting this RelativeSizeConverter to use, we get:

<ScrollViewer x:Name="container" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
    <ItemsControl x:Name="itemsToScale">
        <ItemsControl.Width>
            <MultiBinding Converter="{StaticResource sizeConverter}">
                <Binding ElementName="container" Path="ActualWidth" />
                <Binding ElementName="itemsToScale" Path="Items.Count" />
                <Binding ElementName="scaleSize" Path="Value" />
            </MultiBinding>
        </ItemsControl.Width>
    </ItemsControl>
</ScrollViewer>
<Slider x:Name="scaleSize" Width="100" HorizontalAlignment="Center"
        Minimum="2" Maximum="{Binding ElementName=itemsToScale, Path=Items.Count}" 
        Value="{Binding ElementName=itemsToScale, Path=Items.Count, Mode=OneWay}" 
        IsSnapToTickEnabled="True" TickFrequency="1" />

Notice we use the ScrollViewer’s ActualWidth as our “containerSize”.  The ItemsControl itself has the “totalItems” count, and finally we are using a Slider with the name “scaleSize” to adjust the “visibleItems” count.

Code for the Xbap sample at the top can be downloaded here.

Posted 03-12-2009 by cromwellryan | no comments
Filed under:
Scrolling Multiple Content Areas with a single ScrollBar in WPF

I struggled to solve a UI dilemma while at my current client.  For various reasons, we came across a situation in which we needed to scroll two areas of the view based on a single Scrollbar.  You can see what we were attempting and finally achieved here.

The end result is smooth, yet not quite intuitive so I thought I would share the results and steps taken.  The idea is to use a surrogate ScrollViewer as the source for the offset of a TranslateTransform being applied to content within a seperate ScrollViewer.

Unfortunately, the offset values exposed by the ScrollViewer are both readonly and opposite in force to which we would need to apply to the surrogate.  That is, if we scroll 20 units to the right on our ScrollViewer, we would need to offset the surrogate ScrollViewer by that amount in the opposite direction.  To resolve this problem, we use an IValueConverter to multiple the offset by –1.

Here we can see the Xaml used to layout and hookup this scenario:

<StackPanel>
    <ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
        <Grid>
            <Grid.RenderTransform>
                <TranslateTransform X="{Binding ElementName=mainScroller, Path=HorizontalOffset, Converter={StaticResource multiplyConv}, ConverterParameter=-1}" />
            </Grid.RenderTransform>
            <!-- Content Scrolled by another goes here -->
        </Grid>
    </ScrollViewer>
    <ScrollViewer x:Name="mainScroller" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <!-- Content Scrolled on its own accord goes here-->
    </ScrollViewer>
</StackPanel>

You can see that we have two ScrollViewers and the one which will be controlled (versus the controller) has a container element with a TranslateTransform applied to its RenderTransform property.  This is what we will be using to move the controlled content in the opposite direction of the ScrollBar.

If you find that your content for each are not the same size, you can always use a MultiBinding to accomodate the relative scrolling distance as applied to the offset.

You can find the source to the sample Xbap here.

Posted 03-12-2009 by cromwellryan | 1 comment(s)
Filed under:
STUFF & FOR XML PATH

On the get the job done front, my client had a question today that, while it makes me cringe a little to answer the way I did, it got him moving again.

[Thanks to Mike Levy for pointing me in the right direction]

My client has a small administrative utility that displays Things.  Things can be applied to 0 or more categories.  Looks kinda’ like this:

image

He’s using a 3rd party control for the grid itself which provides really easy filtering, but it wouldn’t work with the data structures to which he had been binding.  So he wanted to know how he could return the category listing as a delimited string directly from the T-SQL.

Here’s the gist of his schema (nothing fancy):

Schema

 

How we solved it:

SELECT Id, Name, STUFF(
            (SELECT cat.Name + '; ' AS [text()]
            FROM Category AS cat
            INNER JOIN ItemCategories AS ic ON cat.Id = ic.CategoryId
            WHERE (ic.ItemId = Item.Id) FOR XML PATH('')
            ), 1, 0, ''
              )
FROM Item

Obviously we would like to move the UI junk out of the DB, but he can deal with that when he understands the 3rd party control a little better.  Right now, he’s giving his customers some more features.

Posted 03-02-2009 by cromwellryan | no comments
Filed under:
The WPF Mindset

WPF is awesome, but it requires the developer to make a pretty big shift in their thinking of UI.  I’ve had a hard time explaining this to people, but last week, I had an opportunity to work through an example with Steve Gentile.  That’s the basis of this walkthrough.

 

The Scenerio

Steve has an ASP.Net website he maintains called ForgottenSkies.com.  One of the pages displays a map from the game with events that were captured from the server.  You can see the ASP.Net version here.  Steve was looking to create a Silverlight version of this page.

The Wrong Mindset

The initial response from most developers would be to put an image on the “form” and then figure out a way to place some composite control or other image that would denote each event’s location.  If they had the inclination they might use the DataContext, but they likely would also iterate each Event in some collection and manually place these controls within some container.  I believe Steve was trying to place them into a really big grid with lots of Rows and Columns to represent the Latitude and Longitude of the map.

The WPF Mindset

Decomposing this scenario is vital to using WPF properly.  When it comes down to it, the map is really just a way to visualize a collection of Events. If we wanted we could easily make this a list, couldn’t we?  So lets start there:

For the purposes of this demo, the Window.DataContext is set to an instance of an AttackService, which looks like the following:

public class AttackService
{
    public ObservableCollection<Attack> Attacks { get; private set; }
    public int MapSize { get; set; }
    public AttackService()
    {
        this.MapSize = 160;
        this.Attacks = new ObservableCollection<Attack>();
        Random random = new Random();
        for(int index =0; index < 10;index++)
        {
            var attack = new Attack
            {
                Description = string.Format("Attack {0}", index),
                Latitude = random.Next(0, MapSize),
                Longitude = random.Next(0, MapSize),
                Type = (AttackType)random.Next(0, 2)
            };
            this.Attacks.Add(attack);
        }
    }
}

Our goal is to display the Attacks collection, so let’s do that:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>        
        <ListView ItemsSource="{Binding Attacks}" />
    </Grid>
</Window>

imageWe have a ListView which has it’s ItemsSource bound to our Attacks collection.  Nothing special.  WPF doesn’t know how to display an Attack class so if we would just see a 10 instances of our class name listed.  We’ll get there though.

 

For starters, lets look at these as if they were listed in a table (or GridView). To do this, we’ll tell the ListView to use a style, attacksList.  We’ll place this style definition in our Window’s Resources collection for convenience of our demo.

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Resources>        
        <Style x:Key="attacksList" TargetType="ListView">
            <Setter Property="View">
                <Setter.Value>
                    <GridView>
                        <GridViewColumn DisplayMemberBinding="{Binding Description}" />
                        <GridViewColumn Header="Latitude" DisplayMemberBinding="{Binding Latitude}" />
                        <GridViewColumn Header="Longitude" DisplayMemberBinding="{Binding Longitude}" />
                    </GridView>
                </Setter.Value>
            </Setter>
        </Style>        
    </Window.Resources>
    
    <Grid>        
        <ListView x:Name="attacksList" ItemsSource="{Binding Attacks}" Style="{StaticResource attacksList}" />
    </Grid>
</Window>

What we’ve done is given ourselves a way to set values or properties on the ListView.  imageFor the sample you see here, we set the type of View for the ListView to be a GridView. 

The Map

The ultimate visualization of this information is to display it contextually in a map.  It’s important to remember that this is still a list, we just want to visualize the list differently.  To do this we need to change our attacksListStyle.

<Style x:Key="attacksList" TargetType="ListView">
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <Canvas>
                    <Canvas.Background>
                        <ImageBrush ImageSource="Images\Map.jpg" />
                    </Canvas.Background>
                </Canvas>
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
    
    <Setter Property="ItemContainerStyle" Value="{StaticResource attackContainerStyle}" />
</Style>

Instead of setting the View of our ListView, we are now setting the ItemsPanel to a Canvas.  This tells the ListView to place all of the items its charged with listing into the Canvas.  We have chosen canvas, because we will want to place each item via coordinates (X/Y, Left/Type) rather than stacking, row/column, etc.  The background of our Canvas is going to be a JPG version of our map.  Backgrounds and Foregrounds are always brushes, so we are using an ImageBrush to draw our map on the Canvas background.

The second property we are setting is the ItemContainerStyle to the attackContainerStyle.  The ListView places each item into a container rather than displaying it directly.  In order to place it correctly, we need to set the Top and Left properties of this ItemContainer.

<Style x:Key="attackContainerStyle">
    <Setter Property="Canvas.Top" Value="{Binding Latitude}" />
    <Setter Property="Canvas.Left" Value="{Binding Longitude}" />
</Style>

This binds the Canvas.Top and Canvas.Left DependencyProperties to the Attack.Latitude and Attack.Longitude properties respectively.  To bring this together, we have our ListView bound to a collection of Attacks and the ItemContainer contains each Attack and has its DataContext set to that Attack it is meant to contain.

At this point we have most of what we want.  imageEach little black image you see below represents an attack.  This is done by setting the DataTemplate for the Attack type.

<DataTemplate DataType="{x:Type local:Attack}">
    <Image Source="Images\AlliedTerritory.gif" />
</DataTemplate>

The problem you will find is that if you allow the Window to be scaled beyond the size of the map size as it existed when creating the Attack Latitude and Longitude, the points on the map will not scale or move with the map.  I dealt with this by implementing an IMultiValueConverter.  I won’t go into it here as it doesn’t pertain to our Mindset discussion, but I’ve included it in the attacked source code.

Summary

If you come into WPF trying to create cool graphics or visualizations from the outset, you will miss the power and productivity of the platform.  WPF and the oft-sited Designer/Developer scenario actually thrive when you begin to simplify your application into the basics and then apply visualizations.

Get the source for this project here:  Source Code.  The Xaml for this is literally only 67 lines with spaces.  There is 1 line of custom code in code behind, and you saw the AttackService above.  It’s dead simple.

Posted 11-03-2008 by cromwellryan | 6 comment(s)
Filed under:
Why VMWare over Virtual PC

I just found the reason why I’m going to slap down almost $200 bucks for VMWare Workstation over Virtual PC: Unity.  I am using a coworkers VM to help on a project he’s been working on, but he uses VMWare and I use Virtual PC.  Instead of buy a license I’m using VMWare Player.  Well I found option under VMWare called Unity so of course I clicked it.   Well it’s possibly the coolest thing I’ve seen ever. 

Here is my desktop with VMWare running as normal:

VMWare Normal

 

and here it is with Unity:

image

All of the windows/applications that were active inside the VM are now native windows in my host.  Also, when you go down to the start button, a second Start Button with the name of the VM becomes visible that allows you to start other apps in this same mode.  I don’t care what you say, that’s just awesome.

Gates/Seinfeld Commercial

So everyone is hating on the new Gates/Seinfeld commercial (you can see it on Windows.com).  Maybe I like Seinfeld humor too much, but I think it's hilarious.  It doesn't inundate me with Windows or Vista glare, it's not over the top, it's just funny.  I mean, Bill Gates just wiggled his rear end on national television!

I guess I'm just easy to please.

TFS Screencasts - Part 2 - Scrum For Team System Features

One of the things we are using here at SDS for our TFS installation and projects is the Scrum for Team System which provides a new Sharepoint Portal layout, Reporting Services reports and graphs, Work Item Templates, and an awesome Process Guidance reference

In this screencast, I try to point out some of these features and how to get to them.  It's short (just over 2 minutes) and I'll dive into each as we continue our storyline.

Shoutout to Camtasia which is sooo simple to use.

Posted 09-04-2008 by cromwellryan | no comments
Filed under:
TFS Screencasts - Part 1 - Create a Team Project

One of the projects I'm working on for my company, Strategic Data Systems, is our internal Team Foundation Server 2008 solution.  I'm working with some of the guys who head up our Agile Development Center to make sure things fit well with what they are doing.  It's been difficult to find overlapping free time, so I have started putting together screencasts to highlight our procedures and what I consider best-practices.  We've published written documentation internally, but these are so much more palatable.

These are geared toward our organization in content, but should be generally relevant to anyone interested in TFS.  This particular screencast walks through creating a Team Project and specifying permissions for implementing Scrum roles.

 Direct Link

p.s This is hosted, for free (as in beer), by Silverlight Streaming Services.  It took all of 20 seconds to sign up and 5 minutes to upload the video made with Camtasia.

Posted 08-27-2008 by cromwellryan | no comments
Filed under: ,
Outlook 2007 does the little things

People give Microsoft Outlook a lot of crap, but if you're willing to think outside the box, you'll realize they did all the little things that make life easy.  For instance, I rarely use the calendar popup for creating new appointments.  No, if I have a meeting next Wednesday, I type "next wed" and hit tab.  It's at 1pm, well, type 1 and hit tab.

Done.

New Appt. Screenshot

SQL Server 2000 vs 2005 Lazy XML Validation

Someone was looking to do quick-and-dirty validation of an Xml document inside a SQL Server procedure today.  I assumed, and regretted, that he meant 2005, which would have looked like this:

declare @xml1 xml 
declare @xml2 xml 
set @xml1 = '<Node1><Node2 attrib="This is it." /></Node1>'
set @xml2 = '<Node1><Node2 /></Node1>'
select Col.value('count(./@attrib)', 'int') as count
from @xml1.nodes('Node1/Node2') as Tbl(Col)

select Col.value('count(./@attrib)', 'int') as count
from @xml2.nodes('Node1/Node2') as Tbl(Col)

After being told, "that blows up", I jogged the memory a bit and came up with this mess:

/* THE STUPID WAY */
DECLARE @hdoc int
DECLARE @doc1 varchar(MAX)
DECLARE @doc2 varchar(MAX)
set @doc1 = '<Node1><Node2 attrib="This is it." /></Node1>'
set @doc2 = '<Node1><Node2 /></Node1>'
/* DOC 1 */
EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc1

IF EXISTS( SELECT    *
FROM       OPENXML (@hdoc, '/Node1/Node2/@attrib',1)
            WITH (attrib  varchar(20)))
BEGIN
PRINT 'Dumb ass'
END
exec sp_xml_removedocument @hdoc

/* DOC 2 */
EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc2

IF EXISTS( SELECT    *
FROM       OPENXML (@hdoc, '/Node1/Node2/@attrib',1)
            WITH (attrib  varchar(20)))
BEGIN
PRINT 'Dumb ass'
END
exec sp_xml_removedocument @hdoc

 

Moral of the store?  UPGRADE!

Posted 08-19-2008 by cromwellryan | 1 comment(s)
Filed under:
Installation Guides

This evening I completed my first split-server (or dual server as it's called in the guide) installation of Team Foundation Server 2008.  I've installed TFS a few times now in single-server mode which is pretty crazy easy when you consider what you get (way more than SVN or CVS by themselves).  Throughout the entire process I actually found myself RTFM step -by-step.  For all the grief that Microsoft receives, you have to give them a ton of credit for their manuals, guides, and walk-throughs.

Reason #29 for using Virtual Machines

Today I blew up a server.  Couldn't figure something out so I pushed every button I could find, flipped every switch and changed every setting.  Nothing.  So you know what I did, I deleted it, copied over a new Sysprepped Hard Drive and had a clean slate in about 5 minutes.

I figured out my problem, by the way.

Posted 08-06-2008 by cromwellryan | no comments
Filed under:
Why Plain Old LINQ is so powerful

Ian Griffiths posted a great example of how powerful and cool LINQ is when used in everyday code (it's not all about databases people).

If you haven't started to learn how to incorporate this awesome toolset into your daily coding life, you're killing yourself.  No excuses.

Posted 07-31-2008 by cromwellryan | 2 comment(s)
Filed under:
Roadblock to Mocking Unit Tests

I've been a faithful unit tester for a few years now.  I may not do everything by the book (I think end-to-end unit tests are helpful), but I do get good coverage most of the time.  That said, I've found myself unable to use any of the Mock frameworks out there, because I don't use your typical Dependency Injection pattern.  That is, I don't like "building up" very freaking instance with all the "Provider" or "Service" interfaces I'm might need in the possible life of a business object.  Yes, if your Customer class is only going to create or save an Order, it feels OK, but my objects are busy dude, so I'd need the longest constructor of all time.

I prefer Dependency Resolution.  I don't use any fancy framework, I just use a good old, DI.Resolve<IBusyBee>() and go about my business.  It works wonderfully, it's light-weight (cause I don't use configuration based DI frameworks), and it's my baby.

That said, it's also been the roadblock to my mocking foray.  That was, until I "got it" today.  Long story short, here's how I roll:

Create a Mock DI Container...

Mock<IDIContainer> mockContainer = new Mock<IDIContainer>();

Create the Injected Mock instances...

Mock<INotificationManager> mockNotifMgr = newMock<INotificationManager>();
Mock<IRepository> mockRepository = newMock<IRepository>();

Tell the mock IDIContainer to return the mock instances when asked...

mockContainer.Expect(c => c.Resolve<INotificationManager>(null)).Returns(mockNotifMgr.Object);
mockContainer.Expect(c => c.Resolve<IRepository>(null)).Returns(mockRepository.Object);

Mock your heart out...

mockNotifMgr.Expect(mgr => mgr.NotifyEmailConfirmation(It.IsAny<Member>())).AtMostOnce();
Member.Register("username", "firstname", "lastname", "ryan@myus.com");

mockContainer.VerifyAll();
mockNotifMgr.VerifyAll();

I'm very happy to have finally jumped on the Moq bandwagon as it will certainly make some unit tests much easier to write.  Maybe I'll even do the test first part more faithfully now. 

FYI, I use my own DI framework which is just a glorified HashTable.  It works for me and it is quick.  Moq has also become my Mock framework of choice for no good reason other than I downloaded it first.

Posted 07-15-2008 by cromwellryan | 14 comment(s)
Filed under:
Video Conferencing Code of Conduct

My team uses ooVoo for video conferencing our Daily Scrum.  It's been great and very reliable.  My only complaint is a lack of whiteboard or desktop sharing, but we've overcome these obstacles with other tools (see SharedView).  Over the months, I've come to acquire an expectation of what the experience should be like and, from that, a Code of Conduct.  Here it is:

Don't Be a Slob - Just cause you're in your bedroom or PJ's doesn't mean I want to know about it.  Put a decent shirt on and brush your hair.  Same goes for yawning, coughing, and every other table manner.  Cover your mouth, mute the Mic, whatever.

Have a Headset - I'm sure some guy out there is ecstatic about the next step in the evolution of the speaker phone, but they still suck in comparison to a headset and Mic that are placed against their corresponding body part.  You're laptop's built in speaker and Mic are no better, so fork out the 10 bucks and get a cheap headset you cheap-***.

Go Full or Go Home - I'm glad your torrents are racing, but your video looks like the corner of your head just entered the Atari zone.  Stop downloading the latest SUSE iso for a few minutes and give me your full bandwidth attention.

Setting up a Virtual PC Domain

I do a lot of demos and Virtual PC 2007 is a mainstay in my arsenal for those demos.  I've used VMWare Server (the free one) and it is very nice, but I run an x64 OS and VMWare had neglected to sign certain emulation drives which caused me enough headache that I ditched it for the easy of VPC. 

I mentioned using Syspreping for my VPC library prior which saves me a ton of time, but one of the things I've always started but never finished was setting up a Virtual Domain.  Well this weekend, I finished things up and I'm happy to say, it wasn't that bad. 

Here's what I did:

Create My Domain Controller Machine by copying a Syspreped Window 2008 Server harddrive image and creating a new Virtual PC using an existing hard drive.  About 120 seconds later I have a free standing vanilla server ready to roll.

imageConfigure Network Adapter(s) by specifying Local Only in the VPC's Network Settings. 

At this point you'll want to log into VPC if you haven't already.  We'll want to isolate our domain and let each of the workstation VPC's communicate with the domain controller by going into the Network Adapter's properties.  Our little domain network is going to be rather isolated.  To accomplish this, we will specify a specific Subnet and IP address range.  Here is what I've used for mine:

IP Range: 192.168.8.1 - 254 (where 192.168.8.1 is my domain controller IP)
Subnet Mask: 255.255.248.0
Gateway: 192.168.8.1 (DC/DNS server)
Primary DNS: 192.168.8.1 (DC/DNS server)

image Setting up Active Directory is a breeze if you do it the easy way.  Of course, I did it the easy way the last time.  (Note to self: when just learning, take the defaults).  Windows Server 2003 and 2008 have this concept of Roles.  A server can fill one or more roles which are the conglomeration of settings, services, etc to do something more abstract... like be a DC.  We are going to add the role Active Directory Domain Services.  

After the Add Role wizard does it's thing, you actually "promote" the machine to a DC by running dcpromo.exe (Start, dcpromo, Enter).  This is where you make your selections, which in this case, I've chosen:

Create a new domain in a new forest
FQDN: vpc.com

You'll want to let the machine also be a DNS server.  This is where I screwed up the first time.  Don't get scared here, with our networking settings this domain we're setting up won't touch your corporate domain or anything crazy like that.

Let the Wizard do it's thing and reboot when it is complete.

Your Active Directory Domain Controller is ready to roll.  Great job.

Adding Workstations is a matter of adding a Computer entry into the Active Directory Users and Computers console and then actually adding the computer to the domain.  You'll find the AD Users and Computers MMC console in Administrative Tools.  Once you've added a computer entry, log into another VPC instance which has the same Network Adapter settings as above (different IP of course .2, .3, etc) and add the machine to the domain (vpc.com) in my case. 

imageHere's a quick screen capture of my Network Adapter on the Workstation I added to the domain.

It's great being able to demo Enterprise software this way or test things like integrated authentication for intranet applications.

Did you know? Screenshots of Virtual PC Instances

If you are running a VPC instance and you'd like to take a screenshot of something on the VPC, did you know you can do that without any photo editing hassle?

Simply make sure you aren't "in" the VPC (hit the right Alt key if you are).  Now click and drag a square around the portion of the VM you want to capture.  CTRL+C or Edit -> Copy will capture the section to the clipboard and you can paste it wherever. 

Nice touch.

Posted 07-07-2008 by cromwellryan | no comments
Filed under:
Why WPF? This is why...

http://dnrtv.com/default.aspx?showID=115

Just awesome!  I didn't see anything far fetched other than they must have a great designer on staff.  I wonder if the designer was doing the Blend work?

Posted 07-02-2008 by cromwellryan | no comments
Filed under: ,
Visitor Pattern with Anonymous Methods

I don't often have the need to implement the Visitor Pattern, but today I was that day.  I looked around really quick for an example of how to do this with Lambda Expressions and Anonymous Methods, which seemed like they were the way to go.  It may be that my search skills have deteriorated right along with my sense of style, but I didn't find much.

I played around for a few minutes and here is what I came up with:

public abstract class CarBase
{
    public void Visit(Action<CarBase> action)
    {
        if (action != null)
            action(this);
    }
}

public class BigCar : CarBase
{
    public void RunOverLittleCar()
    {
        Console.WriteLine("Me smash little car!");
    }
}

public class LittleCar : CarBase
{
    public virtual void RunAwayFromBigCar()
    {
        Console.WriteLine("Go Faster!");
    }
}

public class EcoCar : LittleCar
{
    public override void RunAwayFromBigCar()
    {
        Console.WriteLine("Ouch.");
    }
}
class Program
{
    static void Main(string[] args)
    {
        IList<CarBase> cars = new List<CarBase>(new CarBase[] {
                                                                new BigCar(), 
                                                                new LittleCar(), 
                                                                new EcoCar() 
                                                              });
        foreach (CarBase car in cars)
        {
            car.Visit(delegate(CarBase c)
            {
                if (c is BigCar)
                    ((BigCar)c).RunOverLittleCar();
                else if (c is LittleCar)
                    ((LittleCar)c).RunAwayFromBigCar();
                else if (c is EcoCar)
                    ((EcoCar)c).RunAwayFromBigCar();
            });
        }

        if (Debugger.IsAttached)
            Console.ReadLine();
    }
}

In many implementations of the visitor pattern there is an adapter or actual Visitor interface and implementation class which is passed into the Visit() method.  This is just smooth.

My visit method above is a little big to look good as a lambda expression, though maybe I just don't have the eye for it. 

Posted 07-02-2008 by cromwellryan | no comments
Filed under:
Virtual Property C# Code Snippet

For those of you who use NHibernate you may find this convenient, if you don't already have your own.  Below is a C# code snippet for creating a public virtual property (code and file are both there).  Just put it in your <Visual Studio 2005/2008>\Code Snippets\Visual C#\My Code Snippets folder and you're off and running.  No restart required.

File

Code

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>propv</Title>
            <Shortcut>propv</Shortcut>
            <Description>Code snippet for an automatically implemented virtual property</Description>
            <Author>Microsoft Corporation</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>type</ID>
                    <ToolTip>Property type</ToolTip>
                    <Default>int</Default>
                </Literal>
                <Literal>
                    <ID>property</ID>
                    <ToolTip>Property name</ToolTip>
                    <Default>MyProperty</Default>
                </Literal>
            </Declarations>
            <Code Language="csharp"><![CDATA[public virtual $type$ $property$ { get; set; }$end$]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>
 
 
Attachment: propv.snippet
Posted 07-02-2008 by cromwellryan | no comments
Filed under: ,
Backup Your Site

So last night I was restructuring my hosting infrastructure (read: moving folders around) and managed to delete the folder that hosts most of my sites.  I got that nasty sinking feeling in the pit of my stomach.  I was able to get things back up, but my hosting provider, which is normally pretty responsive and helpful, took FOREVER to respond to my restore request. 

Immediately after that I set up a scheduled job on my home machine to pull down a rar of the site each night.  It's hard to get good help these days.

Jing

http://jing.cromwellhaus.com/2008-07-01_1427.swf

NHibernate Thinks Your Enum is Dirty

Get your head out of the gutter.

It's important to look at your mapping files closely when trying to diagnose unexpected results.  One of our developers had recently added two properties to our big honkin' CustomerOrder entity.  These both happened to be enumeration values, which are represented by Int values in the database.  Of course, NHibernate mapping files (hbm's) are from the POCO perspective, which means the <property type="..." />  value should be the Enumeration's themselves.  If you use Int32, though, things will appear to work, but you're actually causing NHibernate to do an incompatible type comparison during it's "Dirty" checks.  This will cause your lazily, loaded entities to be dirty as soon as you get them.

So, be careful in reviewing your mappings, because it doesn't take much to screw up something small that has a big impact.

Posted 06-30-2008 by cromwellryan | no comments
Filed under: ,
SysPrep Your Virtual PC Images

I create a lot of Virtual PC images, be they for demos, testing, or actual work.  If you haven't started using Virtual PC all the time, start.  When you do, start syspreping your machines and you'll save yourself a ton of time and find Virtual PC that much more useful.

Here is a step-by-step guide.  Run, do it now.

Posted 06-13-2008 by cromwellryan | 2 comment(s)
Filed under:
MiniMVC for WPF

Tonight I presented for the Dayton .Net Developers Group on WPF.  Unlike my previous Lap Around WPF @ CONDG which was meant as a beginners guide to WPF, this time we were skipping the basics and plunging into a framework I've dubbed MiniMVC. 

MiniMVC is, primarily, a set of DependencyProperties and custom ICommand's which allow you to specify a Controller for any FrameworkElement and/or Action in the logical tree.  Unlike Dan Crevier's D-V-VM pattern or Josh Smith's MVC pattern implementations which rely on explicitly defining RoutedCommands for each action, binding them up manually, and other unpleasantries (in my humble opinion - these guys still know more than I) with this framework you can use any old class, with any old method, and start executing actions immediately.  Here's an example:

<Window x:Class="PostDemo.Window1"
      
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      
xmlns:mvc="http://cromwellhaus.com/wpf/minimvc"
      
xmlns:demo="clr-namespace:PostDemo">

    <
mvc:MiniMVC.Controller>
        <
demo:Window1Controller/>
    </
mvc:MiniMVC.Controller>
   
    <
StackPanel>
        <
TextBox x:Name="txtMessage"Text="" />
        <
Button>
            <
mvc:MiniMVC.Action>
                <
mvc:ControllerAction Trigger="Click"Action="Echo"
                      
Return="{BindingElementName=txtResult,Path=Text}">
                    <
mvc:ParameterParameterName="message"
                          
Value="{BindingElementName=txtMessage,Path=Text}" />
                </
mvc:ControllerAction>
            </
mvc:MiniMVC.Action>
          
Write Something
      
</Button>
        <
TextBlock x:Name="txtResult" />
    </
StackPanel>
</
Window>

Here's what's going on:

First, we have this class, Window1Controller, which we are attaching to the Window's MiniMVC.Controller property. 

Second, we are setting the MiniMVC.Action property on the Button to a ControllerAction triggered by the button's Click event.  When Click occurs the Action to be taken on the Controller is Echo.  We want to pass into Echo the value of the txtMessage TextBox Text value as parameter message.  Also, we're specifying that the Return value from Echo should be applied to the Text property of the txtResult TextBox controller.

Cool?  So what's really going on?  Well, MiniMVC is handling the most importantly the OnChange event handler for the Action DependencyProperty and using that to dynamically create an ICommand class called ActionCommand.  It's also looking up the Click RoutedEvent via Reflection and adding the ActionCommand's Execute method as the event handler for the located Click RoutedEvent.  There is ZERO code in my code-behind.  The Designer has free-reign to apply the Controller and action to any RoutedEvent he/she chooses and we can all sleep well knowing our concerns are separated.  A happy marriage in my book.

I must give a lot of credit to Rob Eisenberg's super-awesome Caliburn project on which much of the Action dependency property is based.  His framework is full featured to the tilt, but is a little over done to my liking with the extensive use of Dependency Injection.  If you find MiniMVC useful, though, I highly recommend you watch for progress on Caliburn.

You can download the full solution, including demo's, from the presentation, as well as the above example project here.

Posted 04-24-2008 by cromwellryan | 4 comment(s)
Filed under: , ,
Quicky Visual Studio Projects you can Toss to the Curb

When I'm trying to explain things to people or just want to try something out really quick I'll often create myself a temporary Visual Studio projects that I don't intend to keep around.  In fact, I have an entire Temp folder full of them.  imageI always loved that in the VB 6.0 IDE you could choose not to save your project at all and no remnant would exist if you chose not to save.  Apparently you can do this in Visual Studio 2005 and 2008.   Go into Tools -> Options and select the Projects and Solutions node.  Uncheck Save new projects when created. 

Bingo.

Posted 04-11-2008 by cromwellryan | no comments
Filed under:
Virtual PC and Network Places

I use Virtual PC a lot, especially for development.  I try to emulate a mini-infrastructure of how I'll be deploying my solutions, so no SQL Server on my box, no IIS on my box, etc.  To support this I use Virtual PC Guy's steps for enabling communication between my host and the VPC's.  If you are on an Active Directory environment this can have a pretty negative impact on name resolution, specifically when browsing through "My Network Places" (XP) or just "Network" (Vista).  imageIf you are running into this and it bugs you, go into your Microsoft Loopback Adapter properties and disable/uncheck "Client for Microsoft Networks".  I personally disable everything except Virtual Machine Network Services and IPv4 since this just a small private network running on my computer.

So What's Your Windows Experience Score?

I realize this isn't the MiniMVC post I promised, but that one is a monster and I wanted to feel like I accomplished something this evening.

imageLast week I was forced to replace a dying video card which was a piece-of-junk when I bought it, but, well, I'm cheap.  I picked up an NVIDIA GeForce 8600 GT and while not the best, it's more than I'll need. 

When I built this rig, I picked up about the best available at the time.  Looking at my latest Windows Experience Score, I'm sort of regretting not picking up the Intel 6800 Core 2 Duo, though it was significantly more expensive than the 6600 I  did choose.  I guess I can't fault the decision based on the facts at the time.  That said, my Dell M1530 has the 6800 and I swear it's a friggin' beast.

What's your score?

Posted 03-21-2008 by cromwellryan | no comments
Filed under: ,
IIS 7 is so cool

I'm so behind on IIS 7 it makes me sad.  I love HttpModules and HttpHandlers in ASP.Net (Speedy Rewards transaction processing is based on one I wrote), but this just takes the cake.

Up Next: MiniMVC

Posted 03-20-2008 by cromwellryan | no comments
Filed under:
New Year Indeed

It has been quite a New Year so far.  As of today, Monday January 14th 2008, I have left Speedway and the Speedy Rewards™ team and found new employment with SDS Consulting and I have new eyes courtesy of Lasik Plus of Dayton.  I'd say that's a fairly ambitious first two weeks.

I'm still working on my side project, hoping to have it completed in the next few weeks or so.  I lost focus with all the holiday excitement, but I've picked back up again. 

I'll also be giving another WPF presentation for the Dayton .Net Developers Group.  This one will be more in-depth than my CONDG presentation which focused on some of the basics of templates, styles, and binding.  One of the big spots in this new version of the presentation will be implementing the MVC pattern within WPF.  Very cool.

Posted 01-15-2008 by cromwellryan | no comments
Filed under: , , ,
ASP.Net MVC Checkbox/boolean Value Mapping

In my quest to get my wpfstyle.com site written in the new ASP.Net MVC framework (day 3) I've run across a little issue that I'm sure will come up again.

In my world, a checkbox always seemed to imply true/false or yes/no.  In reality, it can mean a lot of things in an Html Form.  It's an input, remember, and inputs have a value.  When your checkbox is checked, that value is posted back. 

Making it work as a boolean indicator in your MVC application, is possible though.  In keeping with the Membership/Authorization theme from yesterday, I have the following controller action:

public void Authenticate(string userName, string password, bool? rememberMe)
[Hint: Notice the '?' after bool for the third parameter.  That'll be important in a moment.]
Here is the corresponding Login.aspx View which contains a form posting to this action:
<%using (Html.Form("Authenticate", "Account"))
  { %>
    <div style="margin: auto auto 4px auto">Username 
        <%=Html.TextBox( "username") %> </div>
    <div style="margin: auto auto 4px auto">Password &nbsp;
        <%=Html.Password( "password") %></div>
            
    <div style="margin: auto auto 4px auto">
        <%=Html.CheckBox("rememberme", "Remember Me", "true", false)%>
    </div>
    <div><%=Html.SubmitButton( "Log In") %></div>
<%} %>

Looking at our intellisense for Html.Checkbox, we seeimage 

By setting the checkbox's value to "true" we're going to have that value sent back through the MVC pipeline to our Action which has a boolean parameter rememberme.  It's not just any boolean though, it's a nullable boolean.  Remember when I meantion the distinction that the checkbox being checked causes the value to be posted back?  Well if the checkbox is *not* checked, the rememberme value will be null. 

The MVC pipeline is nice enough to implicitly convert the "true" string to a boolean, but null is not necessarily false in all cases.  To account for this, we must make our parameter a nullable boolean.  Does this maybe cross the line into mixing UI and Controller... eh - possibly?

(NOTE: If you don't see the Checkbox method in your intellisense, make sure you picked up and referenced the MVC Toolkit)

Posted 12-20-2007 by cromwellryan | 1 comment(s)
Filed under:
ASP.Net MVC and Forms Authentication

So last weekend I picked up the new ASP.Net 3.5 Extensions Preview CTP (and MVC Toolkit) from the ASP.Net team and I'm loving the MVC bits.  I never could get in to MonoRail mainly because I'm a developer diva.  I need intellisense, syntax highlighting, the whole deal.  For a CTP, this release packs quite a punch.

After running through Scott Hanselman's MVC How-To Screencast and playing around I took to writing a full site I had already 90% completed with Community Server (wpfstyle.com - it's coming).  Blew threw most of the functionality in the first 3 or 4 hours - awesome.  Then I tried to add Forms Authentication through the easy ASP.Net Configuration button of VS 2008.  Nada.

Long story short, I figured out how to get things working, but there are some manual steps.  Here they are:

image[Step 1] Create a new ASP.Net MVC site.  I've called mine SecureMVCApplication.

[Step 2] Lets add a new controller called SecureController.  This will be our set of actions that only administrators can access. 

 

 

image [Step 3] We don't need to add any new Actions, the Index action created for us is sufficient, but we will need to do something.  So add a call to RenderView("Index") within the Index method.  You'll also need to create the index view, so add a folder called Secure under the Views folder already in your project.  To this we will need to add a new MVC View Page item.  To make it clear, I've typed "This is for admin eyes only!!!" as the body of my view.

At this point we should make sure things are working.  Hitting F5 should take you to the root of the site, but you could well end up at /Views/Secure/Index.aspx or something like that.  Try browsing to http://localhost:<port>/secure/index.  You should see the "This is for admin eyes only!!!" text.  If not, go watch Scott's screencast and come back.

image [Step 4] We're ready to start securing things.  Use the ASP.Net Configuration button to set security to Internet, create a couple of users and at least 1 role called Administrators.  This is for our example, you can call your roles whatever you want in your application.

At this point, you would normally use the Create Access Rules link to specify the Adminstrators role has access to the secure directory.  Instead, we have to do this bit ourselves, because the MVC pattern will present us with a URL structure that does not map to physical directories.  At least, probably won't.  In a normal site, the ASP.Net Configuration tool would add a web.config to each configured directory that specifies the authorization rules.  This brings us to the next step:

[Step 5] Open your projects root web.config and add the following:

<location path="secure">
  <system.web>
    <authorization>
      <allow roles="Adminstrators" />
      <deny users="*" />
    </authorization>
  </system.web>
</location>

Assuming you are familiar with MVC URLs this is telling us that the http://<site>/secure path should allow access to users in the Adminstrators role and deny everyone else.  /secure is, of course, the controller.  Had this been a standard site, the stuff inside the <location /> element would have been found inside our secure\web.config.

[Step 5] We are now ready to authenticate our users, but we don't have a normal login.aspx.  Instead, we're going to create a controller called UserController and add a Login and Authenticate action.  Here's what I've added to my sample:

namespace SecureMvcApplication.Controllers
{
    public class UserController : System.Web.Mvc.Controller
    {
        [System.Web.Mvc.ControllerAction]
        public void Login()
        {
            RenderView("Login");
        }

        [System.Web.Mvc.ControllerAction]
        public void Authenticate(string username, string password)
        {
            if (System.Web.Security.Membership.ValidateUser(username, password))
            {
                System.Web.Security.FormsAuthentication.RedirectFromLoginPage(username, false);
            }
        }
    }
}

Notice that my Login action is simply displaying a view.  This view has two textboxes (one marked password) and a submit button.  If you watch(ed) Scott's Screencast, I've used the http://asp.net/downloads/3.5-extensions/MVCToolkit.zip to do this.  The form itself looks like this:

<%using (Html.Form("Authenticate?ReturnUrl=" + this.Request["ReturnUrl"], "User"))
  {%>
    <div>Username: <%=Html.TextBox("username") %></div>
    <div>Password: <%=Html.Password("password") %></div>
    <div><%=Html.SubmitButton("Login") %></div>
<%} %>

Upon Submit/Login, we're POSTing to the Authenticate( string, string ) Action in our UserController which implements the basic Forms Authentication (above).  The next step is optional, but it helped me watch the authorization status.

[Step 6] (Optional)  Add this to your global.asax.cs to see the authorization status of your requests..

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];

    if (null == authCookie)
    {//There is no authentication cookie.
        Debug.WriteLine("Don't know you, dude.");
    }
    else
        Debug.WriteLine("Enjoy the party!");
}

Now F5 and browse to http://localhost:<port>/secure/index and you should be taken to the http://localhost:<port>/user/login page.  Upon hitting login, you're directed back to the root of the site.  In our form, we had to manually set the ReturnUrl, because Forms Authentication assumes you will be posting back to yourself (classic ASP.Net Web Form).  We're posting across to the Authenticate action Url.

You can download the completed VS 2008 project I used here.

Can you believe we're already calling ASP.Net Web Forms "classic"?  Now we need to get MVC into the WPF platform.  How cool would that be!

Posted 12-19-2007 by cromwellryan | 14 comment(s)
Filed under: ,
NHibernate Query Generator Installer for Visual Studio 2008

imageI posted recently a manual .reg file for adding the NHibernate Query Generator custom tool to Visual Studio 2008.  I just sent Ayende an update to the .Setup Product.wxs, a WiX file, which adds a new fixture specifically for 2008. 

If you are interested in building the installer and running the trunk of NHQG, below is my batch script.  Obviously, you'll have to change a couple of paths, but it should get you started. 

You can download the Product.wxs pending Ayende approving the new Product.wxs file here.

echo Off
set path=%path%;c:\tools\svn-win32-1.4.4\bin

echo get Trunk (Non-Recursive)...
svn co
https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk trunk -q -N
echo done

echo get Art...
svn co
https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/Art trunk/Art -q
echo done

echo get SharedLibs...
svn co
https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/SharedLibs trunk/SharedLibs -q
echo done

echo get NHQG...
svn co
https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/NHibernate.Query.Generator trunk/NHibernate.Query.Generator -q
echo done

echo build NHQG...
pushd .
cd trunk\NHibernate.Query.Generator
%windir%\Microsoft.NET\Framework64\v2.0.50727\msbuild.exe default.build
echo done

echo build Installer
cd NHibernate.Query.Generator.Setup
%windir%\Microsoft.NET\Framework\v2.0.50727\msbuild.exe Setup.wixproj
echo done
popd
PAUSE

Posted 12-07-2007 by cromwellryan | 1 comment(s)
Filed under: ,
NHibernate Query Generator with Visual Studio 2008

Custom Tool Configuration I've been using Ayende's NHibernate Query Generator (NHQG) to help type-ify my NHibernate repository queries.  One of the great +1's of his tool is that you can apply it as a Custom Tool for your NHibernate mapping files right within Visual Studio.  

With this setup, every change to my mapping file is reflected in my typed NHibernate ICriteria instances.  For those who work directly with Hibernate Expressions, look how clean my queries are:

// Get it using the Id
public static MyClass GetById(long id)
{
return Repository.Get<MyClass>(Where.MyClass.Id == id);
}
// Get those updated today
public void Example2()
{
IList<MyClass> cards = Repository.Find<MyClass>(Where.MyClass.LastUpdated >= DateTime.Today);
}

That's just awesome!

There's a slight glitch though, his installer only registers the tool for Visual Studio 2005.  I'm sure now that 2008 is RTM (I've been using Beta 2) he'll soon have a new version out, but in the mean time, you can use these two .reg files:

NHQG C# Custom Tool Registration

NHQG VB Custom Tool Registration

Posted 11-19-2007 by cromwellryan | 8 comment(s)
Filed under:
Strangest Support Call... EVER

SRCardHere at Speedway our Speedy Rewards team rotates a support phone for any serious problems.  Usually it's an Oracle Split-Brain, though we have that under some control.  Today it was a little different.  I received a call from one of our business clients asking for help in looking up a customer's information and needed some help.  Didn't seem a Level 3 support, urgent matter, but whatever.  Turns out there is a deceased individual somewhere in a bordering state and all he had on him was our Speedy Rewards card.  The police had contacted our office for help.

Just another reason never to leave home without your card.

PerformanceHelper.cs Update: Perfmon, Console, and Debug Output options

I've updated my PerformanceHelper class that I'll throw around certain code blocks to help trend or monitor performance.  Before it was merely a PerformanceCounter wrapper with a few metrics, but now you can specify Console, Debug and/or Perfmon.  You do this by using an XOR ( '|' ) in a new Constructor.  Here's an example which outputs to Debug.WriteLine and PerfMon:

for (int index = 0; index < 10; index++)
{
    using (new PerformanceHelper("ConsoleSample",
        "Perfmon Sample", OutputOptions.Debug | OutputOptions.Perfmon))
    {
        Thread.Sleep(500);
    }
}

The method that does the Output to Console and Debug is marked as [Conditional("DEBUG")], because you really should have a better strategy for performance monitoring in production and you don't want that hit for each block that you wrapped.

Note to Vista Developers:  You will have problems creating custom performance counters at runtime based on registry access.  To support this in a client based app, you will need to specify an application manifest and mark it with the following:  

<requestedExecutionLevel  level="requireAdministrator" />
For more information on application manifests, read this.
Posted 10-26-2007 by cromwellryan | no comments
Filed under: ,
WPF Controls TabIndex: Moving to the First Input Control

Here's one of those real-world situations that no one bothers to demo.  If you are building a form or have some sort of input your gathering from the user, you'll likely want the first input control Focused initially.  You have a few ways to do this (in ascending order of recommendation):

  1. Call Focus() on the first control explicitly (meh).
  2. Iterate the controls collection and find the lowest TabIndex (terrible code smell).
  3. Do the following in the Load event:
this.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
Posted 10-25-2007 by cromwellryan | 2 comment(s)
Filed under: ,
Lap Around WPF @ CONDG

This evening the Central Ohio .NET Developers Group was nice enough to let me present on WPF.  Everything went fairly well, though it was more a test of my efficiency in WPF development than I had planned; I managed to leave behind the external hard drive that had my code-snippets, slides (both of them), and project template.  So we went from nothing to code-kinda-complete in about an 1 hour and 45 minutes. 

I was very happy with the number of questions and that at least a few people stayed behind to talk afterwards.  If Jim has an opening, I am hoping to give the same presentation again here in Dayton (hint, hint). 

For those that are interested I've posted the Demo project, Time Machine, for your general amusement.  If there are any questions or comments regarding the presentation or the demo, feel free to post them and I'll do my best to answer them.

Thanks to everyone who showed up and for all your questions.

Posted 09-28-2007 by cromwellryan | 3 comment(s)
Filed under: ,
Awesome Tool of the Day: WorkRave

Countdown to Micro-break, Rest-break, and get-out-of-there-break.I found this tool about 5 years ago and then lost it during a job move.  I've been looking for it ever since and finally found it through StumbleUpon today.  Most will find it a little annoying and kind of stupid, but it was great when I stuck with it.

WorkRave is a little status tray application that tells you when to take a break, gives you exercises to do, and locks your computer so you do them.  These aren't "Pump you up!" exercises, but instead blink every-once-in-a-while, keep-your-body-from-atrophy exercises.

One of many exercises presented during a rest break.

You might feel like your doing less at first, but I guarantee you'll feel much better throughout the day and, in the end, be more productive.  Over time, I learned to do some of these things on my own, but this is just a gentle tap on the shoulder.

Visual Studio 2008 Beta 2, Team Explorer, and Codeplex

If you happen to use CodePlex as I do, I hope you found Team Explorer for Visual Studio 2005 to be a huge productivity boost.  With Visual Studio 2008 it wasn't entirely obvious to me how to replicate this setup.  It turns out that Team Explorer can be installed individually from the Visual Studio Team Foundation Server 2008 Beta 2 (what a mouthful) installer without all the extra gunk.  I figured this out when I noticed the Team Explorer for 2005 installer had a graphic for Team Foundation Server. 

So go grab the Microsoft Secure Content Downloader and its a ridiculously quick 1.5gb download - about 45 minutes over my Timewarner cable connection.

Posted 08-08-2007 by cromwellryan | no comments
Filed under:
Exporting Adobe Illustrator resources to WPF

There are a lot of sites out there with great vector resources provided in Adobe Illustrator files.  A few have taken a stab at creating exporters or converts, including Mike Swanson and a CodePlex.com project called XamlXporter

I tried out Mike's XamlExport plugin and it worked fairly well, but he has some well documented items that aren't supported which seem to be pretty common in the AI world.  This lead me to try the XamlXporter which was built for Illustrator C2.  C3 is the latest version and I'm using the 30-day trial.  XamlXporter uses the Illustrator COM Type Library, but apparently Adobe changed the COM GUID for this release.  It was pretty easy to resolve and I've got another post here showing you how to fix that.

Here are some pretty nice sites with some Illustrator Vector resources you can use, but beware of the conversion gotcha's.  WPF is young and Illustrator is, err, mature, so not everything has a translation.

I think we really need a site where people can upload and share WPF resources.  This would be great for styles, templates, etc. which can be time consuming and difficult for non-design people like I.

Posted 08-03-2007 by cromwellryan | 1 comment(s)
Filed under:
XamlXporter COMException Fix

There is a pretty cool, but curiously quiet, CodePlex project called XamlXporter that allows you to export Adobe Illustrator files/resources to WPF files.  This is a great thing since WPF is young and there are a lot of free resources and tutorials for Adobe Illustrator out there, as well as, you will probably find that design firms are going to use Illustrator before Blend for quite while. 

The current version of Illustrator is C3, but the current/latest version of XamlXporter is built for C2.  Apparently Adobe has updated the GUID for Illustrator's COM Type Library, so the XamlXporter won't work with C3.  Here's how I fixed it:

  1. Install Illustrator.  There is a 30-day trial version here.
  2. Download XamlXporter (0.2 Alpha is here).
  3. Open Visual Studio 2005 (you can probably use 2008/Orcas, but I didn't).
  4. Create a new project (I used C# Console), but I'm sure VB WinForms, etc will work just as well.
  5. Add a COM Reference to Adobe Illustrator C3 Type Library.
  6. Browse to the <project>\bin\Debug|Release directory and copy the Interop.Illustrator.dll to the XamlXporter binary directory.
  7. Start up the XamlXporter according to the instructions and Voila!

If you're lazy, you can download the Interop assembly I created here

Awesome Tool of the Day: StumbleUpon Firefox Add-On

The other day I happened upon the Firefox Add-On page and decided to give the recommended Add-On a try.  I've been infatuated ever since.

Though there's an inordinate number of buttons on the default toolbar layout, StumbleUpon is pretty simple: You/others browse the web and when you find something you like you give it a thumbs-up image or a thumbs-down image if you don't.  Then there's the magic button image which randomly picks pages from the submitted pages that are recommended (thumbs-up).  Their pitch says it pretty well..."Channel surf the internet."

I warn you, it is very addictive, but if you choose topics you are actually interested in, you'll find quite a few cool and relevant sites.  Check out my recommended sites so far..

Get the StumbleUpon Add-On

"This problem is being researched"

I'm a big fan of the Vista Problem Reports and Solutions feature.  I'd say it's had a satisfactory solution to real problems +50% of the time, which is better than I can say for any Support FAQ or Help file I can recall.  Today, though, I've been let down.  Here's what I've got - see second screen shot for details:

image

image

Thanks guys.  Appreciate the update.

Binding to an Image Byte[] in WPF

I'm working on a WPF app for my wife who coaches our local high school track team.  One of the features she wanted was to have some images for different players and teams and, religious debate aside, I have chosen to save these in SQL Server 2005.  I'm using NHibernate for all my data access which has been a great experience (my first).  Impressively, NHibernate supports SQL Server Image columns via the inherent Byte[]  type (See Section 5.1.9 of the docs).  This made adding the Image to my classes very easy. 

Here's a snippet of my class with the corresponding NHibernate Mapping Xml File:

/* Class */
[Serializable]
public class Organization : INotifyPropertyChanged
{
//...

public byte[] Image
{
get { return _image; }
set
{
_image = value;
OnPropertyChanged("Image");
}
}

//...
}
<!-- Mapping -->
<
hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
<
class name="Cromwell.MyApp.Organization, Cromwell.MyApp"
table="dbo.Organization">
<
id name="Id" type="Int32" column="Id" unsaved-value="0">
<
generator class="native" />
</
id>
<
many-to-one name="Type"
class="Cromwell.MyApp.OrganizationType, Cromwell.MyApp"
column="Type"
not-null="true"/>
<
property name="Name" type="String" length="255" column="Name" not-null="true"/>
<
property name="Address1" type="String" length="255" column="Address1" not-null="false"/>
<
property name="Address2" type="String" length="255" column="Address2" not-null="false"/>
<
property name="City" type="String" length="255" column="City" not-null="false"/>
<
property name="State" type="String" length="2" column="State" not-null="false"/>
<
property name="PostalCode" type="String" length="7" column="PostalCode" not-null="false"/>
<
property name="Image" type="Byte[]" column="Image" not-null="false" />
</
class>
</
hibernate-mapping>

The key to binding this Image property on my WPF forms is the Binding Converter property.  This property allows you to specify any class which implements System.Windows.Data.IValueConverter to act as an intermediary between your bind data and WPF.  In my case, the goal was to turn a byte[] property, Image, into a BitmapImage which the an <Image /> control/element can display. 

Here's what I came up with:

class BinaryImageConverter : IValueConverter
{
object IValueConverter.Convert( object value,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture )
{
if(value != null && value is byte[])
{
byte[] bytes = value as byte[];

MemoryStream stream = new MemoryStream( bytes );

BitmapImage image = new BitmapImage();
image.BeginInit();
image.StreamSource = stream;
image.EndInit();

return image;
}

return null;
}

object IValueConverter.ConvertBack( object value,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture )
{
throw new Exception( "The method or operation is not implemented." );
}
}

Here's how I used it in my WPF Page:

<Page x:Class="Cromwell.MyApp.EditOrganization"
...
xmlns:converts="clr-namespace:Cromwell.MyApp.Converters"
>
<
Page.Resources>
<
converts:BinaryImageConverter x:Key="imgConverter" />
</
Page.Resources>
<
Grid>
<!--
Image Control -->
<
Image Source="{Binding Path=Image,
Converter={StaticResource imgConverter}}
"
Stretch="UniformToFill"
StretchDirection="Both">
<
Image.BitmapEffect>
<
DropShadowBitmapEffect Color="Black" />
</
Image.BitmapEffect>
</
Image>
</
Grid>
</
Page>

I'm going to have to spend some time in the WPF profiler, but this is a big step.  Pretty cool how simple it was and very clean.

Posted 07-26-2007 by cromwellryan | 3 comment(s)
Filed under: ,
WPF ScaleTransform Direction

The key to scaling your WPF elements in a specific direction other than down and to the right are the CenterX and CenterY properties of the ScaleTransform.  It's easy enough to set these manually, but that's just lazy and asking for long term trouble.  Instead, decide how you want it to animate and bind it to something.  For instance, I have a touch screen keyboard I'm working on that I'd like to animate Up and to the Right when you are holding down the key.  Here's how I did it:

<Page xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
  <Button Margin="5,5,5,5" Width="50" Height="50" x:Name="btnKey">
    My Button
    <Button.RenderTransform>
      <ScaleTransform x:Name="buttonscale" ScaleX="1" ScaleY="1" CenterX="0" CenterY="{Binding ElementName=btnKey, Path=ActualHeight}" />
    </Button.RenderTransform>
    <Button.Triggers>
      <EventTrigger RoutedEvent="Button.Click">
        <BeginStoryboard>
          <Storyboard>
            <DoubleAnimation Storyboard.TargetName="buttonscale" Storyboard.TargetProperty="(ScaleTransform.ScaleX)" To="1.5" Duration="0:0:0.25" AutoReverse="True"/>
            <DoubleAnimation Storyboard.TargetName="buttonscale" Storyboard.TargetProperty="(ScaleTransform.ScaleY)" To="1.5" Duration="0:0:0.25" AutoReverse="True"/>
          </Storyboard>
        </BeginStoryboard>
      </EventTrigger>
    </Button.Triggers>
  </Button>
</Page>

The key is that I bound the CenterX proeprty to the button's ActualHeight property.  If you wanted to scale from some midpoint though, you'll have to specify a Converter in your bind syntax.  This Converter technique is often cited in the ubiquitous "Reflection trick".

Posted 06-28-2007 by cromwellryan | 2 comment(s)
Filed under: ,
PowerShell Profile on Roaming Profile

NOTE: Impatience just leads to frustration.

When I first starting playing with PowerShell here at the office, I was all excited to start adding little cmdlets to my personal profile and add to my stellar productivity (tongue firmly planted in check).  This would hopefully reduce the net loss incurred by my learning PowerShell in the first place. 

So I took the first step and created my empty profile:

ps> notepad $profile

and added a nice little cmdlet to send email.  This will replace that exe tool I've always used to send emails in batch files or just whenever I need to at the command prompt.

$defaultSendMailHost = "emcrs71"
$defaultSendMailFrom = email@email.com

function send-mail( [string] $to, [string] $subject, [string] $body )
{
     $smtp = new-object System.Net.Mail.SmtpClient
     $smtp.Host = $defaultSendMailHost
     $email = new-object System.Net.Mail.MailMessage
     $email.From = $defaultSendMailFrom
     $email.To.Add( $to )
     $email.Subject = $subject
     $email.Body = $body
     $smtp.Send( $email )
}

Start it up again and WHAM... 

File \\<server>\<username>\My Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 cannot be loaded. The file \\<server>\<username>\My Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 is not digitally signed. The script will not execute on the system. Please see "get-help about_signing" for more details.

Sign my scripts?!  How dare you!  I was too annoyed to deal with it and took the ever so appalling step of changing the PowerShell Short cut to point to a local folder on my C drive.  Please don't stop reading as I've learned from my mistakes and have rectified my ways.

A few weeks later I ran across the PowerShell Community Extensions, which I highly recommend PowerShell-er install and, in fact, replaced my send-mail cmdlet above.  PSCX has an option to install it's own profile which I chose, but after that I started receiving the Digital Signing guff. 

In the end, I did what any good PowerShell-er with a growing Profile should do.  I created a cmdlet to sign my profile.  Now I can open PS, type edit-profile (or use my ep alias), save it, and hit sign-profile (sp alias) and I'm good to go.  Here it is:

function edit-profile()
{
    notepad $profile
}

function sign-profile()
{
    dir $Profiledir\*.ps1 | foreach-object { sign-script $_.FullName }
}

function sign-script( $scriptsource )
{
    get-item $scriptsource
    Set-AuthenticodeSignature $scriptsource @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
}

set-alias sm Send-SmtpMail
set-alias ep edit-profile
set-alias sp sign-profile

Now there is a little part I left out and that's creating yourself a certificate, but Scott Hanselman has a very good post that will walk you through this.

Technorati Profile
Posted 06-27-2007 by cromwellryan | no comments
Filed under:
Bind to Method within a DataTemplate

One of my play projects with WPF is a photo viewer for the pictures we put out on http://cromwellhaus.com.  One of the views is a montage of the latest photos with a random RotateTransform Angle applied to each image's RenderTransform.  Getting the view itself set up as cake, but when I attempted to apply the random angle to each image, it wasn't so random.

Here's what happened and how to actually accomplish such a task:

I started out with an ItemsControl, rather than a ListView as most examples show, using a UniformGrid as the ItemsPanel.

<ItemsControl ItemTemplate="{StaticResource photoItem}" ItemsSource="{Binding Source={StaticResource dpPhotos}, XPath=/rss/channel/item}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <UniformGrid HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
</ItemsControl>

I bound the ItemsSource to an XmlDataProvider pointing to the photos RSS feed for Ryan Jr. pictures

<XmlDataProvider x:Key="dpPhotos" Source="http://cromwellhaus.com/photos/baby/pictures_rss.aspx?Tags=Ryan+Jr&amp;AndTags=1" XmlNamespaceManager="{StaticResource rssMapping}"/>

I run our site using Community Server 2007 Express Edition which provides RSS meta extensions for more detailed feeds.  This required that I apply an XmlNamespaceManager to define these extension namespaces.  That's what this is for:

<XmlNamespaceMappingCollection x:Key="rssMapping">
  <XmlNamespaceMapping Uri="http://search.yahoo.com/mrss" Prefix="media" />
</XmlNamespaceMappingCollection>

Here is the DataTemplate used by the ItemsControl to display/render each image.  You'll see this referred to in above as {StaticResource photoItem}:

<DataTemplate x:Key="photoItem">
  <Image Margin="12,12,12,12" Source="{Binding Mode=Default, XPath=media:thumbnail/@url}" ToolTip="{Binding XPath=title}" Width="{Binding Mode=Default, XPath=media:thumbnail/@width}" Height="{Binding Mode=Default, XPath=media:thumbnail/@height}" />
</DataTemplate>

You can see the use of the XmlNamespaceMapping in the XPath=media:thumbnail/@url.  That had me stumped for a few seconds, but opening the project up in Expression Blend and re-adding the XmlDataProvider created the Mappings for me.  (Sidebar: VS 2008 does do this for you - thank goodness)

At this point, we are displaying thumbnails and we are certainly aware that I make poor color choices, but we're on our way.

Almost there...

Applying the RotateTransform is easy...

<Image Margin="12,12,12,12" Source="{Binding Mode=Default, XPath=media:thumbnail/@url}" ToolTip="{Binding XPath=title}" Width="{Binding Mode=Default, XPath=media:thumbnail/@width}" Height="{Binding Mode=Default, XPath=media:thumbnail/@height}">
  <Image.RenderTransform>
    <RotateTransform Angle="10" />
  </Image.RenderTransform>
</Image>

...and it's almost as easy to use the System.Random class to generate the angle.  Just add the following ObjectDataProvider as a Window or Application Resource and bind the Angle property to it:

<ObjectDataProvider x:Key="randomAngle" ObjectType="{x:Type system:Random}" MethodName="Next">
  <ObjectDataProvider.MethodParameters>
    <system:Int32>-12</system:Int32>
    <system:Int32>12</system:Int32>
  </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
...
<RotateTransform Angle="{Binding Source={StaticResource randomAngle}" />

Well when you do this, you'll find that you get the same Angle for every image.  This is because you are actually binding to a single instance of the ObjectDataProvider.  To resolve this we actually have to embed the ODP in the transform itself as so:

<RotateTransform>
  <RotateTransform.Angle>
    <Binding>
      <Binding.Source>
        <ObjectDataProvider ObjectType="{x:Type system:Random}" MethodName="Next">
          <ObjectDataProvider.MethodParameters>
            <system:Int32>-12</system:Int32>
            <system:Int32>12</system:Int32>
          </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
      </Binding.Source>
    </Binding>
  </RotateTransform.Angle>
</RotateTransform>

Tada!image

Now you will find that your angle's aren't terribly "Random".  This is because you are actually asking for a new instance of the Random class each time.  You can tell the ODP within the DataTemplate to use the same instance each time by adding this to the Window Resources:

<ObjectDataProvider x:Key="randomAngle" ObjectType="{x:Type system:Random}"/>

and modifying the Angle binding to the following, telling the transform ODP to use a specific resource instance rather than just giving it a type to instantiate each time.

<ObjectDataProvider ObjectInstance="{StaticResource randomAngle}" MethodName="Next">
  <ObjectDataProvider.MethodParameters>
    <system:Int32>-12</system:Int32>
    <system:Int32>12</system:Int32>
  </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
You can download a mini-version used to write this post here.
Posted 06-12-2007 by cromwellryan | 2 comment(s)
Filed under: ,
Google Gears

I'm not entirely sure what to think of Google Gears.  It seems most people are focusing on the Database portion of the stack, but it's the LocalServer portion that has me confused.  Does this not reek of complexity and severe duplication? 

After first reading through the LocalServer Overview I thought, cool, this thing is going to serve up my server app when the client is offline.  That's kind of sweet, but how do they know what pages people are going to need?  I sure hope they don't cache on demand, because that breaks down with the first button I click?  Maybe they crawl my pages and pick up links, that might work.  Well, it turns out you have to tell them up front what pages to cache either via a Manifest file or via their LocalServer API.  Manifest file is cool I guess, there will undoubtedly be server-side tools to generate these.

What happens if my client's browser has caching disabled or your page's client side cache expires?  How do you get to the first page that loads the Gears API and starts loading the Gears Cache?  Maybe I'm missing something here.

I think I can handle all link activity and user actions requesting pages from the LocalServer.  I'm sure that stuff can be wrapped into our AJAX frameworks; I'm sure Google's Web Toolkit will soon enough.  What about Mashups' though?  Aren't we supposed to be pulling data from site A and displaying it with relevant information from our site?  Is everyone going to start caching everyone else's data?

But, heck, it's not like any of the RIA platforms out there today are doing any better at providing infrastructure to move the Internet App as is to the offline client.  This seems like a decent start.  I personally like the idea of having two different targets: client or web, while providing a different targeted experience for either.  We have too much horsepower and money invested in our personal computers to waste it on a serving local web pages.

We'll see.  It's still only beta.

Classic Web 1.0...

You know you need to reevaluate your web site when you see the following:

Awesome Tool of the Day: Baretail

 Every now and again I find a tool that changes my life.  Baretail is just such a tool.  I don't know what I did before, but it couldn't have been good.  Baretail is a log file reader/watcher that trails the end of your log files.  This may not be too exciting for you, but here in the Speedy Rewards team, we have some terribly verbose 3rd party log files that are our only real insight into activity.  This has made my week!

Vista Sidebar Gadget Developer Experience

Vista Sidebar Gadgets can be cool, but the developer experience out of the box is severely lacking.  Microsoft doesn't provide a Visual Studio project template, so Tim Heuer was nice enough to provide one for us.  He does so via a Web Site template, which makes sense since a Sidebar gadget is nothing more than an Html page with a splash of JavaScript, minimally, of course.  If you are like me, you like to be able to touch something up and then look at it, but I'm not about to edit, copy, run every time I want to see what my little icon change has affected.  Here's a tip to help you out: create a symbolic link in your %userprofile%\AppData\Local\Microsoft\Windows Sidebar\Gadgets directory.  Here's how:

    1. Run Command Prompt as an Administrator
    2. mklink /D "%userprofile%\AppData\Local\Microsoft\Windows Sidebar\Gadgets\<gadgetname>.gadget" "%userprofile%\Documents\Visual Studio 2005\WebSites\<VisualStudioProjectDirectory>"

This allows you to keep your projects where they belong (VS won't let you open a folder in AppData without jumping some hoops anyway) and still reload your Gadget in Sidebar whenever you make changes.

Silverlight: .Net for the masses

While up in Redmond for the WPF Bootcamp, we had a short time to work with some of the WPF/E, now Silverlight, team members.  At the time Silverlight didn't make a whole lot of sense in our strategy.  That said, I hope everyone sees the great potential that comes from some of the features surrounding Silverlight 1.1 specifically.

Let's put this into context. Over the last couple of years, true web-based applications have really started to take shape.  I'm talking Google Docs & Spreadsheets, Yahoo! Local, Yahoo! Pipes and not YouTube, which is a glorified photo sharing site.  A bevy of AJAX toolkits have attempted to fill the enormous development gap between LCD-JavaScript and C#, Java, VB, Ruby, and Python, but there is only so much one can do with JavaScript before you go crazy.

Now imagine some "real" applications that actually attempt to provide a full feature set which accentuates an existing web model.  My favorite example is Shutterfly Studio.  They probably could have given you 20% of the Collage functionality with some goofy JavaScript or lots of uploading and postbacks, but how long would you wait around for your photos to upload while trying out different layouts?  Not long I'd imagine.  This is where Silverlight comes in.

Silverlight takes the untold story of Java and actually runs with it by providing a consolidated branch of the full .Net CLR, including JITter, Garbage-Collector, BCL, Threading namespace, Network stack and more.  Well this is all well and good, but why not just use Flash?  Well, if you want to deploy a Flash application, you are forced to use ActionScript, which doesn't provide nearly the feature set of .Net nor is it useful in any other environment other than Flash, so your experience is isolated.  Flash also doesn't provide the huge WCF communications platform for secure, transport independent communications, WPF for rich interactive media, and one of the most powerful IDE platforms in Visual Studio.

Imagine starting your family collage with Shutterfly Studio at home on your laptop, getting to work in the morning and flipping through real layouts with your pictures at work (lunch of course) and then sending your parents a link to the catalog of pictures where they can browse any layout and order their own version of the collage?  No Shutterfly Studio desktop icon or Start Menu shortcut.  Just a one time 20 second download of the Silverlight CLR - yeah the Silverlight CLR is only 4mb.  That's what removing 90% of the named color members in System.Drawing.Color and asking people to look up the HEX value.

Have fun.

Posted 05-01-2007 by cromwellryan | no comments
Filed under: , ,
Signing your Powershell Profile Scripts

Running with Set-ExecutionPolicy as AllSigned or Restricted with a roaming profile?  Here's a cmdlet pair that will sign all the scripts in your profile directory.  Makes life easier on me as I include a number of scripts into my main profile for readability:

function sign-profile()
{
    dir $Profiledir\*.ps1 | foreach-object { sign-script $_.FullName }
}

function sign-script( $scriptsource )
{
    get-item $scriptsource
    Set-AuthenticodeSignature $scriptsource @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
}

And if you aren't already using Powershell, stop wasting your time with the Command Prompt and go get it.  Don't forget the Powershell Community Extensions

Posted 04-23-2007 by cromwellryan | no comments
Filed under:
Visual Studio Orcas Beta 1

The last few weeks I've felt like a little intern again.  With the WPF Bootcamp and the early stages WCF integration into the Speedy Rewards messaging infrastructure (I'll be posting on this soon), I've had lots of time to play with .Net 3.0 stuff. 

For those that have had a chance to fiddle, there are two feasible options at this point: 1) VS.Net Extensions for WCF & WPF and 2) Orcas CTP's.  The Extensions, in my opinion, were a valiant stop-gap effort to get people started.  This is especially true for WCF, because there isn't a whole lot of design time experience necessary for web services with the exception of those monstrous config sections.  The WPF extensions were OK, but it was basically like having XAMLPad embedded in VS.  Orcas CTPS, on the other hand, have been virtually useless.  The WPF designer crashed regularly and was slower than waiting for me do math in my head.  This may be due to the Virtual PC requirements, since they hadn't yet worked out the issue of Visual Studio 2005 and Orcas living happily side-by-side.

Anyway's, as of today, there is a better #2.  Orcas has hit Beta 2.  Go get it.  There are Express SKU's too, so don't worry if you aren't an MSDN Subscriber, you can join the party too.

Happy coding - go make something cool.

Posted 04-20-2007 by cromwellryan | no comments
Filed under: ,
PerformanceHelper for easy PerformanceCounter integration

In the Speedy Rewards team here we use custom PerformanceCounters quite extensively to monitor and trend our host systems.  You may not know, but our rewards program implements real-time host integration for transactions that are Id'ed as a SpeedyRewards member such that systems like the in-store kiosk, www.SpeedyRewards.com, and any other store you may soon visit can accurately reflect balance updates immediately.  With 1600+ stores doing this and a sub-1 second response time, we need to keep a close eye on things.

Today I was trying to do some preliminary performance profiling on our new WCF based messaging infrastructure.  To make my life a little easier, I put together a PerformanceHelper class that I actually modeling off the Tracer class found in the Enterprise Library 1.1.  To use it, you wrap a section of code you wish to monitor performance for with the following:

using(new PerformanceHelper(CATEGORY, "<BlockInstanceName>") )
{
    //...
}

This will provide you with a RateOfCountsPerSecond32 counter and an AverageTimer32 counter called "Operations/sec\<BlockInstanceName>" and "Average Time/Operation\<BlockInstanceName>" respectively.  You can download the PerformanceHelper class here and a sample project here

Feel free to use and abuse it, but be aware that this has not fully tested and may well contain bugs.  I provide NO warranty or guarantees, so don't come to me when your server blue-screens from a corrupt registry (not that I've ever done that).  Use at your own peril.

Posted 04-19-2007 by cromwellryan | no comments
Filed under: ,
Vacation at your own peril!

A co-worker of mine recently went on vacation for a week.  Here's what he returned to:

We went with a "Little Tikes" theme.

 

 

Rickie is quite the artist. 

We wanted Rick to feel special, so we gave him his very own POS!

 Meetings are going to be so much more productive now!

 

This one should be in the Louvre! 

Posted 04-16-2007 by cromwellryan | no comments
Filed under:
XSL Transforms applied to XML namespaces

I'm pretty sure I have run across this in the past, but apparently I've avoided complex XSL transforms successfully for long enough that my mind was purged of how namespaces impact your transforms.  Today I was working on our .Net 2.0 build process and was attempting to apply a transform to the *.xxproj file that Visual Studio generates, but I was getting anything but what I would have expected.

My goal was simply to copy everything into a new msbuild file, but swap out the <ProjectReference /> elements with <Reference /> elements that pointed to a static version.  Our reasoning's are a topic for another day, but suffice it to say we are control freaks and MSBuild's apparent omniscience is not something we wish to rely on.

Most people tend to avoid namespace in their custom structures, because they are time consuming to get correct and, in many cases, people don't understand XSD well enough (understandable).  We use them in many cases, but we rarely apply XSLT's to these documents so the issue doesn't commonly present itself.  Visual Studio on the other hand, does specify the MSBuild namespace declaration at the <Project /> root.  This means I have to account for it in my XSLT.  Take the following snippet:

<Books xmlns="http://schemas.cromwellhaus.com/samples/books">
<Book title="Applications = Code + Markup" author="Charles Petzold" />
<Book title="SQL Server 2000 DTS" author="Mark Chaffin" />
</Books>

In this case, one would have to specify the <Books /> default namespace in their XSLT in order to reference the elements in their transform.  The corresponding XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl=http://www.w3.org/1999/XSL/Transform xmlns:bks="http://schemas.cromwellhaus.com/samples/books"> 
<xsl:template match="bks:Books" >
<xsl:apply-templates select="./Book" >
</xsl:template>
</xsl:stylesheet>
Microsoft Expression Blend available to from MSDN

One of the cool tools we had a chance to use while up at the WPF Bootcamp in Redmond was Expression Blend.  While there I became pretty engrossed in the ease with which you could create fairly cool animations without an intimate knowledge of Xaml.  This made it all that harder to leave seeing as we had the latest bits at the time (the Release Candidate is available as a 30 trial).  Fortunately, or gratefully?, Microsoft has decided to make it available on MSDN.  That means me!

I will say though, while reading Charles Petzold's book Application = Code + Markup which starts with Code and then moves to Xaml, I believe developers and designers alike will be fooled into trying to generate a number of more complex animations with paths, triggers/timelines, etc. rather than implement new animations via code.  Karsten Januszewski, who we were lucky enough to meet last week, pointed this exact scenario out while I was attempting to mimic the North Face kiosk carousel via a path.  He referenced a previous post of his which shows how to create a custom animation.  Until I grasp the animation framework in WPF, I'll not risk embarrassing myself by attempting to better explain what Karsten already does much better than I.

Posted 04-03-2007 by cromwellryan | no comments
Filed under: ,
WPF Bootcamp Day 2 - Blend

[Update: These are being posted due to the ftp access restrictions at the Microsoft Campus]

Today has been pretty intense which has kept me away from blogging "live".  Today started with Kevin Moore, Program Manager for WPF/Blend(?), and a lightning round with Expression Blend.  As I mentioned yesterday, I'm not a designer, so Kevin had my mind spinning before breakfast had even settled. 

For those dev-signers (developers who design out of necessity) Blend is initially a very overwhelming experience.  Don't expect to create the North Face demo your first time out.  That said, I was able grasp the benefit of a few concepts including DataTemplates and Styles.  This stuff is like OO for UI.  Pretty cool.

  As soon as Kevin had lost me (quickly), I decided to start playing with Blend Styles and Templates.  At the same time, I decided I'd design my own button.  It turns out my reasoning for wanting to do this, super-rounded ends, were already possible in the standard button, but it was a good learning experience.

Styles

Styles are pretty straight forward and many references to CSS have been made.  Styles seem to be a way to share design properties between elements, especially similar elements.  It seems pretty intuitive, but every time you change the visual appearance of a control, even via Visual Studio or XamlPad, you are styling your control/element.  It becomes really powerful as you share these styles across your project by including these styles in your App Resources section.  From within Blend this is pretty easy after you've gone through and stylized one of your controls by selecting that element and going to the Object -> Edit Style -> Edit Copy.   

You can then Right Click your other elements, go to Edit Control Parts (Template) -> Apply Resource and Select the Style you just created.  You now have a sharable style across your WPF application.  I'm still curious about the ability of sharing these styles across multiple projects and applications if you have a suite of tools.  Are these considered Assets for Expression Media?  That would be cool.

Templates

The way I feel Templating is best described in relationship to Styling is to say that Styling helps describe the visual appearance of one or more elements, while templating describes the Element tree that makes up a visual entity.  For instance, my button above used a template to combine two Ellipses and a Rectangle.  But an ellipse on each end of the Rectangle and you've got a rounded edge button.

To get started with templating, I right click on the standard button and drilled down to Edit Control Parts (Template) -> Create Empty.  If you've done cool stuff with your element already, you can Edit Copy and apply that to other elements rather than start over.  I'll go over a demo to create a pretty cool button that uses lots of composite elements to have rollover effects (glow), transition effects, etc.

 

Posted 04-01-2007 by cromwellryan | no comments
Filed under: ,
Powershell

Yesterday I had a had a chance to have dinner and drinks with another group here for a Technology Summit hosted by Microsoft.  They get a bunch of representatives from parallel and alternate technology groups such as PHP, Linux, Java, Python, etc together and discuss they reasons for Microsoft decisions, show off Microsoft focused options for solving problems, and just generally discuss the technology ecosystem. 

One of the people I managed to talk to in depth was an integral part of the Powershell team.  He helped write the language and has been with the team since inception.  I personally have pretty limited experience in the *nix environment so comparing shells is difficult for me, but he helped me understand some things.  One thing he pointed to as a the cause of some angst between *nix administrators and Windows administrators is the ease of administering a *nix system without a full blown interactive session.  A *nix administrator has the option to open an SSH session and has full shell access to the system.  Adding a DNS entry for instance is 3 lines of shell command rather than opening the DNS MMC console, expanding some trees, opening a dialog, clicking a few times, then actually adding the record you intended initially, then confirming it 3 times before closing the console.

Contrary to my understanding, it was an option to recreate the *nix shells in the Windows environment.  Instead the goal was to create a platform that would enable the end-game of creating cmdlets which can/will enable administrators to administer their systems in as productive a manner as any other platform.

One of my questions to him was regarding v2 of Powershell.  He mentioned that the focus would be in 3 areas: remote connectivity (i.e. SSH), a more powerful interface to powershell (apparently there's more to moving around the powershell than arrow-keys and tabbing), and a more broad library of cmdlets. 

Also announced yesterday was the inclusion of Powershell in the upcoming Longhorn Server release.  Very exciting. 

WPF Bootcamp Day 3 - Hardware capability

To avoid disappointing users after they've gotten as far as running your application on their 1997 300mhz Pentium II, determine their capabilities using the RenderCapability.Tier value before hand and notifying them that they'll need to joing the 21st century before running your app. 

Henry Hahn has a quick overview and, the always welcome, code samples of using this value to make your application conform to the different tiers.

Don't forget your bit shifting, cause the Tier is set up to support new Tiers/platforms in future releases.

Posted 03-28-2007 by cromwellryan | no comments
Filed under: ,
WPF Bootcamp Day 3 - FTP Problems from the Technology Center

You may have noticed there were not many blog entries for Day 2.  It turns out there's no way to ftp stuff out of the technology center.  It's hindering my ability to post with pictures/screen captures.  I've got a bunch of posts for you as soon as I figure this out.

 

Stay tuned.

Posted 03-28-2007 by cromwellryan | no comments
Filed under:
Bringing down an Oracle 9i on Windows instance

The Speedy Rewards program is backed by two pretty hefty Oracle 9i RAC instances.  One is for the OLTP and the other for data-warehousing analytics.  Since it's inception we've pretty impressive success with the uptime and performance, though one glaring problem has plagued us now for going on 4 years.  Every 3 days, whoever is on call is required to reboot EACH instance of the cluster to avoid a "Split Brain".  This is compounded by the fact that the third-party software that we have purchased to manage high-performance points, offers, awards, etc. presentation to our members maintains open connections as long as the application server is running, never closing them or validating themselves.  So basically, this third-party software has negated most of the benefit of a RAC cluster in that there is no load balancing (RAC redirects on the initial connection.Open, not between command executions - sticky connections) and there is no failover during our 3 day reboots.  We must effectively go offline every three days for about 10 minutes.  Not good for a <1% SLA on greater than "a lot" (that's lawyer speak) per day.

I could spend all day trying to reiterate their reasoning for maintaining open connections forever, not re-connecting them, or even their decision to take down their entire application server (not physical server but the windows services that encompass their application) when connections begin to fail.  I'll allow you all to come to your own conclusions as to the competence of this company that shall remain nameless.

After 4 years of open "TAR's" with Oracle, numerous consultants, configuration changes, and eventually a plan to migrate these instances to 10g on Linux we believe we stumbled upon the root cause.  We are all aware, I hope, of Windows Perfmon/Performance Counters and how very helpful they can be in giving insight into your running applications.  Well it turns out that Oracle exposes performance counters, but the underlying implementation of these counters login and extract the counter data directly from the target instances.  In order for Oracle to do this it provides a set of configurations for specifying the login, instance information, etc for the counters to use.  Here comes the kicker - that login must be VALID.  Yes, if it's not valid and you have a tool which try to open these performance counters pretty often like MOM your Oracle process will, over time, leak Virtual Bytes and the Oracle Process will crash, causing a Split Brain.

Long story short, if you're interested in crashing an Oracle 9i instance, try to login over and over with an invalid login.  Now would you call that a bug?  A pretty glaring one if you ask me.

Here is a link to the configuration settings article which details what we had to do to resolve this issue.

Posted 03-27-2007 by cromwellryan | 1 comment(s)
Filed under:
WPF Bootcamp Day 1 - Expression

For those who don't already know, I want to make it perfectly clear that I am the last person you would ask to design an appealling interface.  Messaging, thread syncronization, etc I'm your guy, but pretty pictures I am not.

Posted 03-26-2007 by cromwellryan | 2 comment(s)
Filed under: ,
WPF Bootcamp Day 1 - Visual Studio "Orcas" Demo

We moved past the introductions quickly and are getting down and dirty.  Rob Relyea took us through the basics of WPF from the latest Visual Studio Orcas perspective.  Starting simple by creating a button via Xaml and a duplicate example using purely C# code.  I've posted a copy of the sample here for Visual Studio 2005 with the WPF Extensions.

One of the interesting new classes for you code junkies is the ObservableCollection class available now in .Net 3.0.  This class implements the INotifyPropertyChanged interface allowing the dynamic databinding in WPF.  This is cool for all sorts of reasons, but specifically because we can use this dynamic, event based collections infrastructure for in memory lists of more than your list of employee names, but also videos, complex business objects like product definitions, pages in a book that you are rendering, or files in a directory which you are monitoring.

Posted 03-26-2007 by cromwellryan | no comments
Filed under: ,
WPF Bootcamp Day 1

My co-worker Steve and I are here in Redmond this week for a WPF Bootcamp training session.  We started off by meeting the WPF Product Unit Manager, Ian Ellison-Tayler, and Lead Program Manager, Rob Relyea.  Ian ran through some existing WPF applications floating around the intersphere.  As early as it is for WPF, there are some cool apps already.  Take a look at iBloks, definitely a fun little app.  The British Library has a cool XBAP application as well.

Amongst all the glitz and glamour of the pretty pictures and transitions demoed and blogged about are the features of WPF that make those things possible.  One of the questions I found very intriguing involved how Xaml and the "Element-Content" model would affect future standards.  The "Element/Content" model provides the ability to dress up what is still your standard button with content of all shapes and sizes.  Adding animations, movies, complex text to buttons with ease will open up the options for designers and developers to question what is a functional and usable layout for their software.  It was met with snickers, but the comment that market dynamics would play out the designs that are acceptable really holds true that the design standards are moving from the platform groups to the designers.  What an excitingly simple concept.

Posted 03-26-2007 by cromwellryan | 3 comment(s)
Filed under: ,
The multilingual family...

One of the things we have decided we really want to try with Little Ryan is Baby Sign Language.  I've read a number of great first hand accounts and I'm really excited.  Beyond the suggestions that family's who've adopted baby sign language see a reduction in temper tantrums, I'm excited that I'll have at least a few extra months and, maybe, even a years worth of solid communication with my son.

For those that are interested, the link above to My Baby Can Talk provides a great starting point with a dictionary of videos, Getting-Started lessons, etc.  All of the signs in the My Baby Can Talk series are ASL (American Sign Language) signs which means you are on your way to teaching your child a new language.  More and more universities are recognizing ASL as a legitimate foreign language, so why not keep going.

 At the same time that we are learning ASL with Little Ryan, I'm diving back into high school Spanish (Latin American style this time)!  As with most, I blew off my foreign language in high school, but I've always regretted it.  How cool would it be to strike up a conversation with someone in another language.  Not to mention being able to understand when an overworked waiter starts ripping you for being those guys at lunch.

A while back I ran across the Rosetta Stone web site and I tried out one of their demos.  They use a technique call Dynamic Immersion™ that is absolutely awesome.  Why educators feel it's effective (or maybe the better word is efficient) to memorize the <Your-Language-Here> to English dictionary is  beyond me.  Instead, Rosetta Stone completely ignores your primary languages and uses a mix of visual, audio, and written scenes in the target language to make you decipher your way to competence.  This is what we all did as children and, with the exception of our beloved President, it worked out pretty well. 

I've only recently received the CD's and spent a little time, but as I move along I will try to post my thoughts.

WMI and the Win32_Product Class

Our build process is pretty seamless all the way through to an Integration environment which sits right between Development (laptop/workstation) and Certification (keep your muddy paws off land).  With this automation and continuous integration in general, comes a large amount of excess in the form of intermediate versions.  During a recent upgrade to Window 2003 (don’t ask why it took so long) we found that the little utility that keeps this Integration environment clean started getting fussy.  Well it turns out that you have to install the WMI Windows Installer Provider explicitly.  Here’s how to find it:

  1. Control Panel – Add or Remove Programs
  2. Add/Remove Windows Components
  3. Select Management and Monitoring Tools
  4. Click Details
  5. Check the WMI Windows Installer Provider subcomponent
  6. Click Ok
  7. Click Next
  8. Do a jig.

 

Posted 05-31-2006 by cromwellryan | no comments
Filed under:
SQL Reporting Services Unattended Install Documentation Bug
For those that are trying to package and deploy the SQL Reporting Services 2000 Designer tools, there is a little bug in the documentation. It states that in order to include the Reporting Service Books Online feature, you should use the setting RS_BooksOnline_ as an ADDLOCAL parameter value. In fact, the Template.ini and documentation give the example RS_BooksOnline_EN. BUUUUUUT, it really should read RS_BooksOnline_1033. Just a hint in case you run into it, 'cause you'll have to go looking through MSI logs to find it.
Free March Madness Video Feeds? I'm so there!
I don't understand how more media content providers don't see the benefit of a free test drive. I'll be all over CBS Sportsline for the March Madness On Demand live video feeds free for the first three rounds and I'm sure I'll get sucked into paying for the rest of it.
Posted 03-06-2006 by cromwellryan | no comments
Filed under:
Windows Live Messenger Beta Update
This week the Windows Live group released an update to the Windows Live Messenger Beta (MSN Messenger 8.0). There were a couple of major things with the initial release that I reported and they seem to have been resolved. If you'd like to give it a chance, I have a few new invites that I can give out to those who are interested and I'm sure I'll receive some more shortly thereafter. Leave your email in the comments and I'll do my best.
Rehearsal Dinner at Claddagh Pub

We booked the Claddagh Pub in Mason for the rehearsal dinner.  If you haven't been there, it's amazing.  They actually brought Irish builders over to design and show the construction crews how to make the place look like an authentic Irish Pub.  And the Guinness Stew is amazing!

Dayton-Cincinnati Code Camp reflection...
Well the Dayton-Cincinnati Code Camp and my presentation have both come and gone. In all, the day was a success, but I was a little disappoint in my session. Nothing in-particular went wrong, but I just never felt we got into a good flow. I feel exhaustion took a toll on my presence, but other than that, I can't explain it. Maybe Andy Roddick and I have just misplaced our mojo temporarily. We'll have to see. Our gracious host Jim Holmes did a fantastic job. He says there were glitches, but I never saw them. I was impressed by the number of sponsors who actually showed up with gifts. Here are the session I went to before ducking out a bit early to help a friend move... again. Oh the life of a truck owner :/
  1. Python and IronPython by Catherine Devlin
  2. Little nap to make up for no sleep the night before.
  3. Lunch by Microsoft - who would miss that!
  4. Windows Workflow Foundation by Mike Wood
I was pretty impressed with Python and IronPython, though it mostly has to do with the cool embedded interpreter in the presentation tool. I can't imagine using it for anything other than a toy. WWF was very impressive. A little confounding as it seemed to jump around a lot, but I'm sure that will tighten up a bit. I'll definitly be using that in the near future. I'll have the code from my presentation up on the site soon, so hopefully no-one came running right after the presentation.
Posted 01-23-2006 by cromwellryan | no comments
Filed under:
Windows Live Mail (Hotmail Kahuna) a work in progress.
As I mentioned yesterday, I received my Windows Live Mail beta invitation and I've begun using it full time. It's definitely a functional beta and I must say it's much quicker than it's predecessor, but I'm very glad this is not a completely open beta. It's pretty unpolished at this point and there are some glaring issues in my opinion. We'll see how things far in the next update. Here is what I've found so far:

Bugs

  • Allow sender does not show content.
  • New Mail doesn't appear until you click on or update the folder list
    1. On page 2
    2. Sent email from another account
    3. Windows Live Messenger said I had an email
    4. Paged to page 1 (no new email and count still at 2540)
    5. Page 2 forward to 2 again (no change in count)
    6. Clicked Junk e-mail folder
    7. Inbox went bold and said I had one email
    8. Clicked Inbox (there it was!)
  • The Insert Search Link icon is cut off.

Feature Issues

  • No full screen view of messages!!!
  • Stop trying to be so fancy... Attach a File link rather than stupid drop down. Less is more.
  • Tool bar is very tacky and unorganized. Actions on the email should be together (i.e Send, Save Draft, and Cancel should be next to each other, followed by Attach)
  • Consider using the telerik r.a.d editor... it's amazing!
  • The folder and mail windows do not scale at all when going above 1024x768. UPDATE: This must have been a temporary thing, because it scales just fine now. Let you know if it happens again. I've sent these via the ginormous Send Feedback image/link on every page. I'm sure I'll come up with more.
Windows Live Mail (Hotmail Kahuna) is here!
I received my invitation to Windows LIve Mail (Hotmail Kahuna) today! This on top of the Windows Live Messenger invite I received last week make me believe this first quarter is going to be an exciting one to watch. I have yet to really dig into this new Hotmail release, but rest assured I will let you know what I think soon.
Windows Live Messenger Beta Invites
I have 3 invites left for Windows Live Messenger and so I'll follow the lead from which I receive my invite. First 3 emails in the comments will receive an invite. I'll remove your emails shortly there after so you don't get harvested.
Windows Live Messenger Beta
I recently got in on the Windows Live Messenger Beta courtesy of Jan Tielen's and I've got to say, I'm a little sceptical. The real difference is in the interface, not the functionality (how much can you really do with text based chat?). They have tried to create a more impressive interface, but I believe its a little too clunky. It is a beta, but it doesn't bode well for "ma and pa." Here are my initial reactions:
  • Like the adjustable color scheme.
  • Dislike the horrid orange default color scheme.
  • Love the folder sharing.
  • Dislike not being able to share the same folder with multiple contacts.
  • Love the new contact form and contact card.
  • Hate the clunkyness of the roll-over, expand contact feature, though the idea may have a future.
  • Like the "name-wheel" for searching for contacts, but my parents won't even notice it.
  • Dislike the stupid tabs - there has to be a better way.
In general, I would have expected more polish even for an invite only preview. Scott (like I know him :P) mentioned the pixelated icons, but the same issue runs through the entire app. The pop-out tabs are rough around the edges and the now-green MSN-men which replace the impossible-to-recognize personalize icons of MSN 7.5 are a little fuzzy. I like that they are trying to make things look cool, but please, go vector, go home. Screen Shots
Mono hits the road
It looks like Mono will finally be a valid option for deploying applications. Red Hat has announced that it will include Mono in its Fedora Core 5. Does that mean it will be in Red Hat as well? I couldn't tell you since I don't follow the Linux distributions to closely, but that would definitly be impressive. I personally run Ubuntu and, being a Linux novice, find it to be the closest thing to a "Mom-usable" Linux OS out there. Then again, I don't follow the Linux distributions to closely.
Posted 01-11-2006 by cromwellryan | no comments
Filed under:
Community Server and w.Bloggar Settings
This is really just for my future reference, but since I had a hard time finding out here are the settings I used for w.Bloggar and Community Server 2.0

API Section
  • Blog Tool/API: (Custom)
  • Account Alias: Ryan @ CromwellHaus.com
  • Ping: Weblogs.com
  • API Server: www.cromwellhaus.com
  • Path: /cs/blogs/ryanc/MetaBlog.ashx
Custom Section
  • Posts:: metaWeblog API
  • Categories: metaWeblog API - Single
  • Templates: Blogger API
  • Defaults for everything else
I found the starter for these on the CS MetaBlog API Thread
New Year Goals refresh...
Many moons ago I realized I was not a naturally directed individual. That is, I do not organize well without putting forth a deliberate effort. If and when I fail at something I can most often trace it to a lack of task management on my part. I have found that having a simple list has done more for my career and life than just about anything else I can imagine (please stop boiling over with arguments, I'm merely making a point). In a "kill two birds with one post" moment, I wanted to publish my goals refresh which have made their way into my list of things to do:
  • Publish my experiences on learning the IronPython and Scheme languages.
  • Run 9 miles per week.
  • Lift 3x a week.
  • Blog 3 articles a week (bird #2).
  • Play basketball 2x a week.
  • Read 2 books on the Crusades (this currently exists as "find 2 books about the Crusades").
Now I know what your thinking, "Those certainly appear to be New Year Resolutions, Ryan." Well they are not - they are goals. They are goals, because aside from the last three items they are unchanged from last week, last month, and all of last year. I prefer to maintain rolling resolutions rather than one time resolutions that are tied to dates. Some of the best advice: "Never put off until tomorrow what you can do today" - J. A. Spender
Posted 01-05-2006 by cromwellryan | no comments
Filed under:
Dayton-Cincinnati Code Camp

The final schedule for the Dayton-Cincinnati Code Camp to be held January 21st has been released.  I'm really looking forward to Jim Weirich's session on Ruby on Rails and the especially interesting Developing for Windows Media Center (with Xbox 360!) session by Jason Follas and Greg Huber. 

I'll be following Mike Wood with a session on WSE 3.0.  I plan to recreate the Generic WSE Host service tool we use at Speedway to deploy new services which don't have an otherwise reliable or acceptable host process.

Posted 01-05-2006 by cromwellryan | no comments
Filed under: