Saving Files from Silverlight (using Caliburn)

We’ve been working on a Silverlight project that could be classified as a Line Of Business application (whatever that means).

There have been a few places where we need to allow users to save files. First, I thought I might give you a peek as to how we do this with Caliburn .

Imagine that we are displaying a table of data and that we are allowing the user to export that data to a csv file and save it to their desktop.

How We Do It

In the view, I have a button that looks like this:

<Button pf:Message.Attach="Export" 
        Content="Export Data">

pf is defined as

xmlns:pf="clr-namespace:Caliburn.PresentationFramework;assembly=Caliburn.PresentationFramework"

You can read more about Message.Attach in the Caliburn documentation.

The view is associated with a view model, and that view model has a method:

public IEnumerable<IResult> Export()
{
    var saveFileResult = new SaveFile { DefaultExt = "csv" };
    yield return saveFileResult;

    if (saveFileResult.FileStream == null) yield break; //null means the user clicked ‘Cancel’

    var content = FormatAsCsv();

    using (var writer = new StreamWriter(saveFileResult.FileStream))
    {
        writer.Write(content);
        Caliburn.Core.Invocation.Execute.OnUIThread(writer.Close);  
    }
}

The Message.Attach in the view binds the button to this method on our view model. IResult is a poor man’s coroutine and you can read more about it here.

It’s not that obvious when discussing the save file scenario, but this approach is really useful when dealing with asynchronous actions, such as interacting with a web service. Also by using the SaveFile abstraction, we could more easily test this method. (Though newing it up here sort of nullifies that, but I digress.)

But what is the SaveFile class anyway?

public class SaveFile : IResult
{
    public string Filter { get; set; }
    public string DefaultExt { get; set; }

    public string SafeFileName { get; private set; }
    public Stream FileStream { get; private set; }

    public void Execute(IRoutedMessageWithOutcome message, IInteractionNode handlingNode)
    {
        var dlg = new SaveFileDialog
        {
            Filter = Filter,
            DefaultExt = DefaultExt,
        };

        if (dlg.ShowDialog().GetValueOrDefault(false))
        {
            FileStream = dlg.OpenFile();
            SafeFileName = dlg.SafeFileName;
        }

        Completed(this, null);
    }

    public event Action<IResult,Exception> Completed = delegate { };
}

It a simple abstract for opening and managing the SaveFileDialog. If you want to know more, check out the Caliburn documentation and sample (or harass Rob Eisenberg to post more). Rob also had an introductory post on IResult.

Coming Soon

My rant about Silverlight’s inadequate SaveFileDialog.


Posted 09-25-2009 3:30 PM by Christopher Bennage
Filed under: , ,

[Advertisement]

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)