Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

Top 5 blog posts of mine in 2010

Thought I’d give this one a try – 5 posts that were accessed by visitors of my blog the most and were posted in 2010:

1. Add version 4 components to your Silverlight 3 application with MEF: I wrote about using MEF (Managed Extensibility Framework) to import and offer additional capabilities to users that have Silverlight 4 installed (over the ones that only have Silverlight 3).
2. Reactive Extensions #3: Windows Phone 7: First look at Reactive Extensions for Windows Phone 7. I (re)used the same code I used with my Silverlight / WPF demos show ItemsControl items appearing with a nice animated way.
3. Silverlight Layout States with Reactive Extensions: This post laid the ground for the previous post, showing, how the effect is done.
4. Named & optional parameters in Silverlight 4: I wrote about named & optional parameters that were in the latest Silverlight 4 release. Mostly useful when dealing with Office interop.
5. Display “My Pictures” in Silverlight application at design time: An attempt to hack up a Silverlight design-time ViewModel that would look into your Pictures folder and display any pics that were there.

Thanks for visiting my blog!



My “What’s new in Silverlight 4 demo” app

What’s new in Silverlight 4? Isn’t Silverlight 4, like, old news by now?

Well yes, as the matter of fact, this is one of those long overdue posts that have a hard time getting out. As I’ve been showing these demos since Silverlight 4 Beta came out, this is really the high time I release the source code… Especially when we’re looking to get a fresh preview of Silverlight 5 in the near future.

So here it is – the source code of my Silverlight 4 sample project.

You can also see the project live.

And the rundown of what you can expect to see in the demos:

Fluid layout : Layout states

The first thing you’ll notice when running the demo app is a few images finding it’s way on the screen from the left, sequentially, one by one, with a nice animation. This was done by using new layout states, found on the ListBoxItem. The new LayoutStates (BeforeLoaded, AfterLoaded, BeforeUnloaded) can be used to add a story to your ListBox items. With common ListBox, the effect of items just mysteriously appearing in the box can be confusing to the user, and the same goes for them suddenly disappearing from it. By using animation, you can tell the story of where they came from and why, as well as to where they go when they are removed. Or you just want to prettify your UI a bit. Whatever… Anyway, looking at the code for this reveals nothing really special – the items are simply added to the list:

MenuItems = new ObservableCollection<MenuItem>();

menuItems.Add(new MenuItem { Caption = "WB", ImageUri = new Uri("Assets/html.png", UriKind.Relative), DataContext = "WebBrowser" });
foreach (var videoDevice in CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices())
{
    menuItems.Add(new MenuItem { Caption = videoDevice.FriendlyName, ImageUri = new Uri("Assets/video.png", UriKind.Relative), DataContext = videoDevice });
}
menuItems.Add(new MenuItem { Caption = "RTB", ImageUri = new Uri("Assets/rtb.png", UriKind.Relative), DataContext = "RichTextBox" });
menuItems.Add(new MenuItem { Caption = "Paste", ImageUri = new Uri("Assets/paste.png", UriKind.Relative), DataContext = "Paste" });
menuItems.Add(new MenuItem { Caption = "CLS", ImageUri = new Uri("Assets/clear.png", UriKind.Relative), DataContext = "" });

Nothing special, but there are a couple of tricks: first, to make items appearing one by one, I’ve used a timer:

DispatcherTimer startTimer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(0.2)};
int menuItemCount = 0;
startTimer.Tick += (s, e) =>
                       {
                           MenuItems.Add(menuItems[menuItemCount]);
                           menuItemCount++;
                           if (menuItemCount >= menuItems.Count)
                           {
                               startTimer.Stop();
                           }
                       };
startTimer.Start();

There is actually a better way of doing this now – Reactive Extensions, which I blogged about a couple of posts ago.

Second, I’ve used the BeforeLoaded and AfterLoaded layout states for animating the ItemsControlItems to transition from “non-existing” state to “loaded-and-visible" state. In other words, make them appear on their place in the ItemsControl through animation.

Third – what’s an ItemsControlItem? Out of the box, LayoutStates are only set on the ListBoxItem, if you want to use them on a plain ItemsControl, which also serves as a base for the ListBox, you have to create some kind of workaround, which includes a new class for your item container – ItemsControlItem. See the code for the example.

TextBlock Text trimming

In the menu which appears on the left when you start the app, you may or may not see the text in one on more boxes trimmed. This is achieved with a new property called TextTrimming. Set it to WordEllipsis to enable the trimming:

image

WebCam support and VideoBrush

In the menu code above you might’ve noticed the CaptureDeviceConfiguration.GetAvailableVideoCaptureDevices() enumeration loop – that’s how you enumerate your video-capable devices. Have many webcams plugged in? They’ll all show up in your menu – with the same icon and their name, probably truncated (see above). Hover your mouse over it to reveal their full name in the tooltip.

Clicking the video icon will get you a box with live preview of video stream of the selected cam. The box is an ordinary Rectangle with its Fill property set to VideoBrush, pointing to the selected video device capture source.

Only one VideoBrush can consume a single capture source, but several visual elements can share the VideoBrush. Click on the same video icon again to get another icon with the same video feed.

If you’ve got more than one, you can click on additional video icons to get video feeds from your other cams.

Oh, and running inside browser, you’ll see a nice security dialog, asking you to confirm you’re ok with that cam go live.

MouseWheel support

With video box out on the canvas, hover your mouse over it and play with your mouse wheel – the box will shrink and expand. This is achieved through the MouseWheel event, which many of the Silverlight 4 controls have. Some of them already have their own implementation of the event, generally they don’t.

In this case, a created a MouseWheelBehavior that can be applied to an element to make it work (on a Canvas). You would probably have to adapt it to use it properly; for the sake of this app, it works ok.

The interesting thing here is that if you have a multi-touch monitor, you can try a pinch zoom gesture on the box and it should shrink/expand as well => nice to see Windows APIs being used in Silverlight.

By the way, in this demo, you can drag’n’drop items on the canvas around…

WebBrowser and WebBrowserBrush

WebBrowser in Silverlight is funny… Running the app inside browser and clicking the WB icon will get you a simple box with the “HTML is enabled only in Out-of-Browser mode.” text inside. Run the app outside the browser (installed) and you’ll see a ‘proper’ web page:

image

The links demonstrate different aspects of browser features. Note: the last link will work only when application is installed with elevated trust (set as default with the accompanying sample code).

Adding another “browser” by clicking on the WB icon for the second time will actually bring up a rectangle, filled with the WebBrowserBrush. WebBrowserBrush mimics the referenced WebBrowser appearance at the time it was called on. Because it’s a snapshot it doesn’t react on WebBrowser changes, but you can update it the WebBrowser’s current state by calling the Redraw () method on it.

Right Mouse Click

UIElements in Silverlight 4 support right button clicks in applications, which can be conveniently used to implement a context menu. In fact, Silverlight Toolkit has an implementation of this already ready to use. This application shows how simple it is to implement. Right-click on any of the added elements to change its shape.

RichTextBox Control

A few fresh controls were introduced with Silverlight 4, RichTextBox is one of them. The app shows the simplest demo of it.

NotificationWindow

When clicking a RTB (RichTextBox) icon, a notification window will be displayed on the bottom right corner – another new control. Works outside of the browser only.

Silverlight app as a drop target

Go to your pictures folder and drag some pictures onto the app canvas – they will be shown inside the application – shows integration with the “outside world” / your app can accept files drag’n’dropped into it.

Copy/Paste

Copy text or Xaml and paste it into the app – a text element or a drawing will appear on the canvas. I usually demo this with the Expression Design – draw a shape, choose some colors for stroke and fill, than copy its Xaml (select the shape, then press Ctrl+Shit+C / Copy XAML) and paste into the app. The Xaml will deserialize into a nice Silverlight shape.

Data binding enhancements

Silverlight 4 also extends the data binding with some new properties. In sample code, you’ll notice a couple of running time labels displayed in the bottom right corner of the screen – those will display how the new properties work: the StringFormat property will let you specify the string format right there in Xaml, the TargetNullValue property value will be displayed when the source property value is null, and the FallBackValue will be displayed when there’s an error with the binding itself.

Commanding

Buttons in Silverlight 4 can be assigned objects, implementing an ICommand interface, allowing for implementing separation pattern, well known from Silverlight’s older brother WPF. There are a few commands you’ll find in the sample project – FullScreenCommand, PrintCommand and DelegateCommand, the latter being mostly known for its use in MVVM pattern implementations.

Full Screen pinning

One of the best new Silverlight 4 features is definitely the ability to ‘pin’ the application to a non-primary monitor, which is especially handy for video players. To enable it, you just have to set the FullScreenOptions:

Application.Current.Host.Content.FullScreenOptions = isFullScreenWhenUnfocused ? FullScreenOptions.StaysFullScreenWhenUnfocused : FullScreenOptions.None;

Check the FullScreenCommand in source code for the implementation.

Printing

Basic printing was introduced with Silverlight 4 – you can construct individual printing pages and send them to the printer as bitmaps – enough for simple(r) scenarios, but much better things are on their way in Silverlight 5. PrintCommand shows the simplest possible implementation for printing a page visual.

Other

There are some other Silverlight 4 features you’ll find in the sample code and I won’t be discussing here. Like MEF (Managed Extensibility Framework) or COM interop. And .NET RIA Services, but I don’t know how well they’ll play since the project is dependent on an older version.

Feel free to explore the source code. Just note – it’s demo code so don’t expect much on a best practices side…



My NTK10 slide decks

Another NTK has ended, and in my opinion, this year’s conference was one of the greatest and most enjoyable for the past few years. This is a list of sessions I had (alone or with co-speakers), along with the PowerPoint slide decks (all in Slovenian Language):

Silverlight and MEF

[The Photo Gallery application I was showing is available on the CodePlex and will be updated with the latest bits shortly]

ASP.NET, WebForms, Silverlight – What to choose?

Having @dusanzu as a co-host, this was a Birds of Feather (BoF) session. And although not listed as such, it turned out great anyway. There wasn’t much slides since this was a discussion – the slide-deck will be available from the NTK site.

Silverlight and WCF RIA Services

[I built a basic NTK schedule viewer app from the scratch, using Silverlight Business project template and showing off different features of RIA Services in the process. If somebody is interested in seeing the code that was produced on the talk, please contact me]

Tips & Tricks: Expression Blend for Developers

Again, we (@krofdrakula and I) wanted to show as much useful information and show designer-developer workflow, so we concentrated on showing off Visual Studio, Expression Blend (through Team Foundation Server running in a cloud), and the result was only a two-slide PowerPoint slide-deck (which will be available for download from the NTK site as well). As it turned out, even those two slides were way too much for what we wanted to share in a 45-minute time slot.

What’s new in Silverlight 4?

[The source code accompanying this slide-deck is way overdue for publishing – stay tuned for my future blog posts, where I’ll cover all the features I put together in my Silverlight 4 demo app]

A big thanks to all that attended my talks, I hope to hear from you in the near future. Another big thanks goes to local Microsoft office, for organizing another great event.

Oh, and another thing – this year’s NTK conference was covered through twitter as well (significantly better than last year, but still, plenty of room to improve for the next year). I’ll sign off with the snapshot of Twedge, a Silverlight 4 widget, finding its way to the CodePlex later this week. To see it in action, visit http:/www.ntk.si.

image

See you next year!



Add version 4 components to your Silverlight 3 application with MEF

Note: this post and accompanying source code was updated to reflect the latest MEF build on Codeplex. This build is much more aligned with the version of MEF that is available from Silverlight 4 Beta SDK.

The current Silverlight version is v3, with v4 in the making (in Beta 1 at the time of this posting). Silverlight 4 is bringing a lot of new features in the core framework and to use them, you would have to migrate your applications to the latest version, once it gets released. And that would require all the potential users to upgrade their machines to the latest version as well.

But there’s another way. By using MEF (Managed Extensibility Framework), you can extend your existing Silverlight 3 application with optional package, which would contain Silverlight 4 components only.

Here’s an example: user can select an image file from your local disk in Silverlight 3 only through an OpenFileDialog, while with the new drag/drop feature in Silverlight 4, she would be able drag a picture from the file system and drop it onto the application. Why not allow those with Silverlight 4 installed do it the easy way?

To make this work, the main application should be all Silverlight 3. We’d provide additional Silverlight 4 features in a separate XAP package, which would be downloaded later and tested for the right runtime version. In case user had the latest Silverlight runtime installed, we could bring in additional features in the application. For this post, I’m going to implement the abovementioned picture select feature by providing two controls:

  • a select button for choosing the picture through an OpenFileDialog (Silverlight 3 feature)
  • a drop canvas where user can drop the picture from the file system (Silverlight 4 feature)

Silverlight 3 control

Here’s how the BrowseForPictureControl would look like:

imageThis control would be contained in the main application. It exposes the PictureSelected event, with the FileInfo data passed as an event argument. Because the application is going to subscribe to this event for each control that exposes it, we need to make an interface for it and put that into a new project that would be shared among the both packages.

public interface IPictureControl
{
    event EventHandler<PictureSelectedEventArgs> PictureSelected;
}

public class PictureSelectedEventArgs : EventArgs
{
    public FileInfo File { get; set; }

    public PictureSelectedEventArgs(FileInfo file)
    {
        File = file;
    }
}

The control implements the this interface as:

private void OnBrowse(object sender, RoutedEventArgs e)
{
    OpenFileDialog dialog = new OpenFileDialog();
    bool result = dialog.ShowDialog() ?? false;
    if (result)
    {
        OnPictureSelected(dialog.File);
    }
}

Silverlight 4 control

The improved Silverlight 4 control should be created in a new Silverlight 4 application project, that would be disconnected from the main project, but referencing the previously created shared project. The control looks simpler too:

image

And the interface implementation:

private void OnDrop(object sender, DragEventArgs e)
{
    IDataObject dataObject = e.Data as IDataObject;
    if (e.Data == null)
    {
        return;
    }
    FileInfo[] files = dataObject.GetData(DataFormats.FileDrop) as FileInfo[];

    OnPictureSelected(files[0]);
}

OK, controls done. Now, on to MEF.

Bringing in MEF

MEF for Silverlight 3 is available for download from Codeplex. You’ll need the following assemblies added as a reference in your main application:

  • System.ComponentModel.Composition
  • System.ComponentModel.Composition.Initialization.dll

The second assembly is only required to use from the main project, where composition is performed. The project that is shared between the SL3 and SL4 projects can reference just the first assembly from the list. Also, one downside of maintaining the compatibility with Silverlight 3 is that the Silverlight 4 project must reference the same System.ComponentModel.Composition assembly as other projects. No ‘native’ SL4 MEF there…

Attribute for version

Obviously, loading any Silverlight 4 based code into a Silverlight 3 application should be impossible, therefore we need to mark both of controls with information about the Silverlight runtime they require. Something in a way of:

[ExportablePictureSelector(RequiredVersion = "3.0")]
public partial class BrowseForPictureControl : UserControl, IPictureControl
{
    ...
}

for Silverlight 3 control, and:

[ExportablePictureSelector(RequiredVersion = "4.0")]
public partial class DragDropPictureControl : UserControl, IPictureControl
{
    ...
}

for Silverlight 4 control.

The ExportableSelector attribute is derived from MEF’s ExportAttribute and is declared as:

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ExportablePictureSelectorAttribute : ExportAttribute, IPictureSelectorMetadata
{
    public ExportablePictureSelectorAttribute()
        : base(typeof(IPictureControl))
    {
    }

    public string RequiredVersion { get; set; }
}

Putting it all together

The main application provides a catalog of all the controls that were discovered:

[ImportMany(AllowRecomposition = true)]
public ObservableCollection<Lazy<IPictureControl, IPictureSelectorMetadata>> PictureControls { get; set; }

The PictureControls collection will change whenever a new export is discovered by MEF. When that happens, the newly discovered control will be added to the main form:

private void OnPictureControlsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    foreach (Lazy<IPictureControl, IPictureSelectorMetadata> view in Views)
    {
        Control c = view.Value as Control;
        if (!panel.Children.Contains(c) && Application.Current.Host.IsVersionSupported(view.Metadata.RequiredVersion))
        {
            panel.Children.Add(c);
            view.Value.PictureSelected += OnPictureSelected;
        }
    }
}

The above code shows that the main criteria for adding the control on the form is that it’s RequiredVersion is supported by the runtime – and that is checked with the interop IsVersionSupported method of the plugin host.

When picture is selected, the PictureSelected event is fired by the control and handled to display the picture:

private void OnPictureSelected(object sender, PictureSelectedEventArgs e)
{
    BitmapImage bi = new BitmapImage();
    bi.SetSource(e.File.OpenRead());
    image.Source = bi;
}

Of course, BrowseForPictureControl control being included in the main project, it will immediately be picked by MEF and inserted in the PictureControls collection. For Silverlight 4 based XAP package, however, we need to download it first. Here’s the InitializeContainer method, which initializes a new composition container and triggers the package download:

private void InitializeContainer()
{
    PackageCatalog catalog = new PackageCatalog();
    catalog.AddPackage(Package.Current);
    CompositionContainer container = new CompositionContainer(catalog);
    container.ComposeExportedValue(catalog);

    CompositionHost.InitializeContainer(container);

    Package.DownloadPackageAsync(new Uri("CrossVersioning.Version4Enhancements.xap", UriKind.Relative), (e, p) =>
    {
        if (p != null)
        {
            catalog.AddPackage(p);
        }
    });

    PartInitializer.SatisfyImports(this);
}

The Silverlight 4 package is asynchronously downloaded from the server and added to the package catalog. The last line is there to start the initial composition, causing the v3 control to immediately show up.

Conclusion

There… the application is set up. Users, having the Silverlight 3 runtime installed, will see the it as:image… and Silverlight 4 users will also see that additional feature:

image

This approach will let you gradually update your applications to use Silverlight 4, not forcing the users to update to the latest runtime immediately (although there would probably be no reason not to ;))

You can test the application right here:

Or download the source code from here. Enjoy.



My MEF articles published on SilverlightShow

My two-part article on rebuilding an existing Silverlight application to use MEF (Managed Extensibility Framework) for “selective composition” is now live on SilverlightShow.net (part 1, part 2). I took my Halloween Gallery application and made it pluggable so I can pull in different themes throughout the whole year (current themes include Halloween and Christmas).

Halloween Live Gallery Christmas gallery 

The original features are still there – geotagged photos are retrieved from Flickr API and the location where they were shot is shown on the Bing Map. If you’re interested in MEF, take a look at let me know what you think. The application will be released to Codeplex soon.