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

Page 1 of 1 in the UX category(RSS)

Animation Hack Using Attached Properties in Silverlight

Posted in Silverlight | UX at Monday, March 23, 2009 7:27 AM Pacific Standard Time

In my last post I blogged about using Attached Properties to get around the limitation that only Dependency Properties can be animated. One astute commented noted that he was guessing this could be applied to animations as well and the answer is yet it can. However, it requires one extra step that makes it a little less appealing.

Also I mentioned in my last post, I got this idea from the Climbing Mt Avalon workshop at MIX which has now been posted online and I would recommend watching if you’re doing Silverlight or WPF work. And now on to the code…

Typically if you want to animating something like the width of a grid in a column that isn’t animatable either because it isn’t a double, color, or another easily animatable type, then you would declare a dependency property on your own host class, usually a UserControl, and then animate that instead. A good example is this blog post on the subject which is what I’ve referred to many times.

However, if we take the attached property route instead of putting the code in our user control, we could declare our own attached property to do the work for us. Here is a simple example:

public static class Attachments
{

    public static readonly DependencyProperty ColumnWidthProperty =
            DependencyProperty.RegisterAttached("ColumnWidth", 
            typeof(double), typeof(Attachments), 
            new PropertyMetadata(
                new PropertyChangedCallback(OnColumnWidthChanged)));

    public static void SetColumnWidth(DependencyObject o, double value)
    {
        o.SetValue(ColumnWidthProperty, value);
    }

    public static double GetColumnWidth(DependencyObject o)
    {
        return (double)o.GetValue(ColumnWidthProperty);
    }

    private static void OnColumnWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((ColumnDefinition)d).Width = new GridLength((double)e.NewValue);
    }

}

Once we have this code we can now simply animate the attached property like so:

<UserControl x:Class="SilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SilverlightApplication1"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.Resources>
            <Storyboard x:Name="expandBlue">
                <DoubleAnimation Storyboard.TargetName="blue"
                                 To="300" Duration="0:0:1" />
                <DoubleAnimation Storyboard.TargetName="red"
                                 To="100" Duration="0:0:1" />
            </Storyboard>
            <Storyboard x:Name="expandRed">
                <DoubleAnimation Storyboard.TargetName="red"
                                 To="300" Duration="0:0:1" />
                <DoubleAnimation Storyboard.TargetName="blue"
                                 To="100" Duration="0:0:1" />
            </Storyboard>
        </Grid.Resources>
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="blue" local:Attachments.ColumnWidth="200" />
            <ColumnDefinition x:Name="red" local:Attachments.ColumnWidth="200"/>
        </Grid.ColumnDefinitions>
        <Rectangle Grid.Column="0" Fill="Blue" MouseLeftButtonDown="Blue_MouseLeftButtonDown" />
        <Rectangle Grid.Column="1" Fill="Red" MouseLeftButtonDown="Red_MouseLeftButtonDown"/>
    </Grid>
</UserControl>

Unfortunately if you try the above code (after adding in the mouse event handlers) it won’t work. Why not? Well there seems to be an issue with animating custom attached properties when setting the target property directly in code (actually you’ll notice I left that out above. However, there is a way around it which I found over on Ed’s blog which is to set the target property in code. So here is the code behind with the work around:

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
        Storyboard.SetTargetProperty(expandBlue.Children[0], new PropertyPath(Attachments.ColumnWidthProperty));
        Storyboard.SetTargetProperty(expandBlue.Children[1], new PropertyPath(Attachments.ColumnWidthProperty));
        Storyboard.SetTargetProperty(expandRed.Children[0], new PropertyPath(Attachments.ColumnWidthProperty));
        Storyboard.SetTargetProperty(expandRed.Children[1], new PropertyPath(Attachments.ColumnWidthProperty));
    }

    private void Blue_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        expandBlue.Begin();
    }

    private void Red_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        expandRed.Begin();
    }
}

Once we set the target property via code, then everything works great. However, that is a pain and makes things a lot less clean. But still I think this is a useful approach to animating the properties that are not easily animatable.

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.

Developing User Experiences

Posted in Avanade | Silverlight | UX at Saturday, November 22, 2008 6:42 AM Pacific Standard Time

About six months ago I decided to take a break from blogging without feeling bad about it. It was a nice break, but really my lack of blogging was mostly due to the type of work I was doing. I was working on an interesting project for a large media and entertainment company that combined Microsoft Excel and Project Server 2007 with lots of .NET 3.5 goodness like WCF and WF. While it was an interesting project, I wasn’t really working with the technology that really interests me: Silverlight.

But I’m excited to announce that Avanade has gotten serious about UX and has created a UX practice in the west region (where I work). I’m very fortunate to get to be a part of the leadership team for this practice and I’m excited to see where things are headed. So I’m now a User Experience Developer and I get to work with the technologies that I’m passionate about like Silverlight and WPF.

So what does it mean to be a User Experience Developer? Well, I feel like that is something that I still have to figure out. I know that putting User Experience in front of Developer doesn’t suddenly make you better at UX. However, I think it is much like when you first start out as a developer, you don’t really know what it means yet, but you’re setting out to become a developer. So hopefully by focusing on becoming better at UX I will in the process become a true UX developer and I’ll be bringing this blog along for the ride.

I’ve actually been working on a Silverlight project for the last couple of months and have some blog posts in the works already. So keep an eye out from some Silverlight related posts coming soon.

Page 1 of 1 in the UX category(RSS)