Creating a Dialog service for Windows Store apps using Caliburn.Micro

November 28, 2014

no comments

When you want to display a dislog screen in windows store apps, you can use Flyout, MessageDialog or Popup

the first two should be used for the simple cases – message prompts, question, basic user interaction.

But if you need to display a richer dialog then Popup is the right fit.

The MVVM way to open those dialogs is by using some kind of DialogService that will be called from you ViewModels.

in all the sample i’ve seen on using Popup it always has a strong coupling to the View itself, meaning the Popup was embedded inside the view layout and was triggered to appear by changing the IsOpen property to true.

I wanted to create a service that creates the popup for me, no matter from where i call it. for me, the right approach is to open the popup above the application Frame.

Since im a Caliburn.Micro fan and since Caliburn is the framework with i did it in Caliburn style.

public class DialogService : IDialogService
    public virtual Task ShowPopupAsync<T>(object context = null, IDictionary<string, object> settings = null) where T : IScreen
        var rootModel = IoC.Get<T>();
        return ShowPopupAsync(rootModel, context, settings);
    public virtual Task ShowPopupAsync(IScreen rootModel, object context = null, IDictionary<string, object> settings = null)
        var taskCompletionSource = new TaskCompletionSource<bool>();

        var popup = CreatePopup(rootModel, settings);
        var view = ViewLocator.LocateForModel(rootModel, popup, context);

        popup.Child = view;        

        ViewModelBinder.Bind(rootModel, popup, null);
        Caliburn.Micro.Action.SetTargetWithoutContext(view, rootModel);

        SetPopupPosition(popup, view);
        var activatable = rootModel as IActivate;
        if (activatable != null)

        var deactivator = rootModel as IDeactivate;

        popup.Closed += delegate

                rootModel.CloseView = null;
                if (deactivator != null)



        popup.IsOpen = true;
        return taskCompletionSource.Task;

    private void SetPopupPosition(Popup popup, UIElement popupContent)
        var windowContnt = Window.Current.Content as UIElement;

        popupContent.Measure(new Size(Window.Current.Bounds.Width, Window.Current.Bounds.Height));
        popupContent.Arrange(new Rect(0, 0, popupContent.DesiredSize.Width, popupContent.DesiredSize.Height));

        var horizontalOffset = Math.Max(0, Window.Current.Bounds.Width / 2 - popupContent.DesiredSize.Width / 2);
        var verticalOffset = Math.Max(0, Window.Current.Bounds.Height / 2 - popupContent.DesiredSize.Height / 2);

        popup.HorizontalOffset = horizontalOffset;
        popup.VerticalOffset = verticalOffset;

    protected virtual Popup CreatePopup(object rootModel, IDictionary<string, object> settings)
        var popup = new Popup();

	popup.IsLightDismissEnabled = true;
        ApplySettings(popup, settings);

        return popup;

    bool ApplySettings(object target, IEnumerable<KeyValuePair<string, object>> settings)
        if (settings != null)
            var type = target.GetType();

            foreach (var pair in settings)
                var propertyInfo = type.GetPropertyCaseInsensitive(pair.Key);

                if (propertyInfo != null)
                    propertyInfo.SetValue(target, pair.Value, null);

            return true;

        return false;


One intersting thing about Popup is that it supports light dismiss, meaning i can close the popup by clicking outside its region, I decide to turn this option by default, you can always override it by passing false inside the settings dictionary.

Caliburn knows how to make the connection between the IScreen.TryClose() method and the Popup IsOpen property so i dont need to handle it by myself.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>