On the Silverlight Insiders mailing list there’s been a discussion about the difficulties of handling animations when trying to use an MVVM architecture. I’m not going to go into the details here, as I am going to cover this more fully in a future blog post, but still, I could not resist showing off the elegant way that Caliburn solves this problem. Here is some XAML:
<TextBox x:Name="username" />
<PasswordBox x:Name="password" />
<Button Content="Login"
pf:Message.Attach="Login(username.Text, password)" />
And here is the code from the ViewModel that Caliburn execute when the user clicks the button:
public IEnumerable<IResult> Login(string username, string password)
{
_credential.Username = username;
_credential.Password = password;
var result = new Result();
var request = new GetUserSettings(username);
yield return new ProcessQuery(request, result, "Logging In...");
if (result.HasErrors)
{
yield return new ShowMessageBox("The username or password provided is incorrect.", "Access Denied");
yield break;
}
var response = result.GetResponse(request);
if(response.Permissions == null || response.Permissions.Count < 1)
{
yield return new ShowMessageBox("You do not have permission to access the dashboard.", "Access Denied");
yield break;
}
_context.Permissions = response.Permissions;
yield return new OpenWith<IShell, IDashboard>();
}
Please note that the 1st, 2nd and 3rd yield statements above are all *asynchronous*, but the code within this action is executed in sequential order. The 1st yield also triggers an animation...I can also do things like this:
yield return new BeginAnimation("MyCoolAnimation");
yield return new BeginAnimation("This animation is next");
yield return new BeginAnimation("This animation plays last");
This gives the View Model a declarative way to handle animations without a need to reference the view. Also, it should be noted that the above action relies on several UI services, but I can unit test this action without needing to mock anything. The declarative nature of the action allows me to iterate over the results and simply use normal Asserts on the values. Async programming becomes synchronous and playing Animations is peachy ;)
More on this later, but I just had to show some code because I’m not sure many people know you can do this with Caliburn. On my current Silverlight project, we are making extensive use of this. It makes calling web services a breeze.
Posted
07-10-2009 12:21 AM
by
Rob Eisenberg