Feed Icon  

Contact

  • Bryant Likes
  • Send mail to the author(s) E-mail
  • twitter
  • View Bryant Likes's profile on LinkedIn
  • del.icio.us
Get Microsoft Silverlight
by clicking "Install Microsoft Silverlight" you accept the
Silverlight license agreement

Hosting By

Hot Topics

Tags

Open Source Projects

Archives

Ads

Twilight 1.5: Multiple Views with MVVM

Posted in Silverlight | UX | Twitter at Thursday, February 26, 2009 3:15 AM Pacific Standard Time

You may have noticed the new look for the Twilight Twitter Badge on my blog a few weeks ago. I wanted to add a few new looks for the badge and got one of them done but then decided I need to spend some more time on it before releasing it because I didn’t like the way the code was turning out. There were a couple of things I didn’t like:

  1. The code was too tightly coupled to the views/skins. This made it hard to add new views/skins without duplicating code.
  2. The views/skins weren’t blendable at all.

To start my rework I began with this post by the Expression Blend/Design team on simulating sample data in Blend. The post is a very simple yet workable solution for displaying design time data in Blend so that you can work on the layout of your application. The only change I made was how I detected design mode. After playing around with that sample I decided that to implement this in Twilight I would need to switch to a Model-View-ViewModel approach so I started doing some research into using this approach with Silverlight. In my research I came across this post by Ryan Keeter on using MVVM in Silverlight. It was a nice simple explanation that made sense to me so I set out to combine the expression team example and this MVVM example.

What I ended up with is pretty close to MVVM. I say pretty close because I don’t think it fully fits since the ViewModels hook into some of the Views Storyboard events and also control the Views VisualState transitions. Maybe that fits into MVVM, but it probably breaks some of the rules. However, for this tiny application it makes things a lot easier. I still have multiple Views per ViewModel and the Views have zero code which is what I really wanted.

There are two ViewModels that I’m using: ListViewModel and RotatingViewModel. Then on top of these two ViewModels are four Views: Default, Large, Small, and Tiny.

ListViewModel Views  

Default View

Large View

The ListViewModel is for views where there is just a list of tweets while the RotatingViewModel is for views that display a single tweet at a time.

RotatingViewModel Views  

Small

Tiny

 

 

 

 

You can switch between these views by setting the mode initParam equal to the view you want (example: mode=tiny). The Tiny view looks like the twitter counter badge but then pops the bubbles over the surrounding content. This is done using the windowless = true parameter and absolute positioning. Right now the Silverlight will float over the content below it even when the bubble isn’t showing, so you won’t be able to click through to that content. I might be able to figure out a better way to handle it, but for now that is a known limitation.

Since now all the view logic is in the ViewModel, writing tests is a lot easier. I’m still using the same Silverlight test framework, but thanks to this post by Justin Angel I added a few more complex tests using his WaitFor extension. The test coverage is still very light and I’m not testing the views at all, but I feel like I’m starting to get testing in Silverlight.

I’ve also added another option for hosting Twilight on your blog. You can now host it via Silverlight Streaming using an iframe. Add the following HTML to your page:

** Hosting it via Silverlight Streaming doesn’t support the Tiny mode since the Silverlight won’t be able to expand outside of the iframe.

In addition to hosting it via Silverlight Streaming, you can always self-host it or use the xap I have hosted on dreamhost at http://twilight.bryantlikes.com/twilight.xap. If you’re already using the hosted version, you can switch the mode by using the mode initParam as I mentioned above.

Hopefully this will serve as a great twitter badge for your blog and also a decent example of MVVM in Silverlight along with some unit testing examples as well. Feel free to join the project on Codeplex and create your own views. I am still working on at least one more version that will make the colors tweakable and maybe even detect what colors should be used based on the surrounding html.

Detecting Design Mode in Silverlight

Posted in Silverlight at Wednesday, February 25, 2009 1:46 AM Pacific Standard Time

One of the things I’ve been trying to getting a better understanding of is how to make the Silverlight projects I work on more blendable:

In general, WPF and Silverlight controls should be "blendable". ItemsControls need to display representative data within the design surface.

The problem, at least for me, is that every example out there to detect design mode uses:

var designMode = !HtmlPage.IsEnabled;

Since the Html Bridge is disable inside of Blend, this does work for the most part, but what about when your xap is hosted on another server? In this case the Html Bridge is disabled by default so if someone doesn’t configure it correctly they will get your design time data.

Mode HtmlPage.IsEnabled
Blend false
Visual Studio false
Local Xap true
Remote Xap false*
Streaming Silverlight true**

* This can be changed to true, but it is disabled by default.
** Enabled by default

So I was trying to come up with another method to detect design mode in Silverlight and here is the best I have come up with so far:

public bool IsDesignTime()
{
    try
    {
        var host = Application.Current.Host.Source;
        return false;
    }
    catch
    {
        return true;
    }
}

What happens is that Application.Current.Host.Source works great when the plugin is hosted in a web page and will return the path to the xap file, but in design mode trying to access that property throws an exception. So if you hit the exception then you’re in design mode, otherwise you’re in a web page. Not super elegant but it feels better to me than checking if the Html Bridge is enabled since that isn’t a true check.

Update: As Tom mentions in the comments, you can also use DesignerProperties.GetIsInDesignMode. But if your goal is to make your project more blendable then Visual Studio support might not be important.

Mode DesignerProperties.GetIsInDesignMode
Blend true
Visual Studio false
Local Xap false
Remote Xap false
Streaming Silverlight false

So with this check worst case you get no data in the Visual Studio designer, but the Visual Studio designer isn’t that great anyway. Blend is the real goal. So instead instead of the above code you can use this code instead:

public bool IsDesignTime()
{
    return DesignerProperties.GetIsInDesignMode(Application.Current.RootVisual);
}

Thanks for the tip Tom!

Running a Home Office Web Server with a Dynamic IP

Posted in General | Windows Server 2008 | Community Server at Tuesday, February 10, 2009 2:19 AM Pacific Standard Time

I’ve blogged about my server closet in my home office before. I used to have three servers running in my home office and for Internet service I had AT&T DSL with 5 static IP addresses. That all changed by accident when I was looking into current pricing and found I could upgrade my speed and I would get a lower cost. However, someone over at AT&T DSL misread my order and changed me from static to dynamic, so yesterday morning I got knocked offline. I spent over 2 hours on the phone with them and they told me it could take up to 48 hours before they could get me static IP addresses again. So I started looking into getting my blog back online with a dynamic IP.

One of my goals for last year was to outsource most of my home network to external servers because I didn’t like dealing with it. So last year I did outsource email to Google Apps, DNS and some websites to Godaddy, and Subversion to Dreamhost. Because of that I was able to downsize to a single server which I run a few websites on. I also had been having network speed issues so I had just purchased a new router+dsl modem, the D-Link DSL 2540B which happens to support Dynamic DNS.

Setting it up:

  1. You need to make sure your router supports Dynamic DNS and you need an account with a Dynamic DNS service. I used dyndns.com since they have free accounts. I setup mine to be bryantlikes.dyndns.org.
  2. Delete the A record for your DNS (if you have one) and then create a new CNAME for your domain that points to the Dynamic DNS name. So, for example, blogs.sqlxml.org has a CNAME that points to bryantlikes.dyndns.org. If you have other CNAME records already (for example, www), then point those to your dynamic DNS entry as well.
  3. Forward port 80 to your web server in your router settings. This is different for each router, D-Link calls it Virtual Servers under the advanced tab.

At this point your website should be available from the Internet. However, internally you won’t be able to hit it. The port forwarding only happens from the WAN interface and not the LAN one. In order to get it working internally you have to take a couple more steps.

  1. Setup DNS on your web server if it isn’t already on there. Then add a new domain for the domain that you used in your dynamic DNS. For example, I added the bryantlikes.dyndns.org domain and then created an A record for the root that points to my web server’s local IP address.
  2. Make sure your DHCP clients all point to your web server as their DNS. It is the only DNS Server that redirects the dynamic DNS entry to your local server.

That’s it! You should now have your dynamic IP serving up web pages both internally and externally. This caused me a bunch of headaches and googling yesterday so I thought it was worth blogging about. I glossed over lots of setup in each of the steps so if you want more information let me know and I’ll try to add it.

A Year of Climbing Mountains

Posted in General | Cycling at Wednesday, February 4, 2009 3:54 AM Pacific Standard Time

This post is actually about cycling more than coding, but as I thought about it I realized that being a Software Developer is often much like mountain climbing. Each time I get to what I think is the peak (or close to the peak) I see that there is another even higher peak up ahead. For instance, I’m finally getting comfortable with Silverlight 2 and just starting to get a glimpse of Silverlight 3. A Software Developer can never stop learning (especially if you’re a web developer). I still remember my first glimpse of the .NET/FX mountain range at PDC 05 which we now know to have peaks such as WPF, WCF, and even Silverlight. It was very overwhelming at the time, but now it is fun to look back at where I was then. Quite a view from up here. With all the new stuff coming this year, Win7, Silverlight 3, VS 2010 (betas at least), it will be a year of climbing for sure.

But the real climbing that inspired this post is climbing on my bike. Last year I got serious about riding my bike and did three big rides: 62.5 mile ADA Ride, 100 mile Coolbreeze Century, and the 175 mile MS Socal Ride. At the start of the season I rode mostly flats with a few hills but pretty much hated climbing. During the ADA ride I kept up with a pack of riders that were much faster than me but I would quickly get dropped every time we hit any kind of a climb. After that I started riding Rockstore once a week during the Wins Wheels shop ride and would ride Santa Susana once or twice a week. I did enough climbing prior to my century that I didn’t get passed a single time on any climbs and I was the one dropping the pack. On the MS ride I did get passed on one climb (by a girl), but that was because I was resting the in the shade so that I didn’t pass out from heat exhaustion. :)

I’ve actually started to enjoy climbing and so this year I’m planning on doing two rides: Cruising the Conejo and Ride Around the Bear. Both are century rides, but both have a lot of climbing. Cruising the Conejo has 6,000 feet of climbing while Ride Around the Bear has 10,000 feet of climbing. I just started to train for them in earnest this week and sometimes I wonder if I’m crazy to attempt these rides. Right now I know I couldn’t do it, but that is how you get to a place you want to be. You plan to get there at a later date and set that date in stone, otherwise you’ll never get there.

So this year is a year of climbing for me, both in cycling and in software. Hope to see you on one of the peaks!