RadWindow in Caliburn Micro

3 posts, 0 answers
  1. Stefan Buys
    Stefan Buys avatar
    22 posts
    Member since:
    Dec 2009

    Posted 30 Mar 2011 Link to this post

    Requirements

    RadControls version Silverlight Q1 2011 

    .NET version 4

    Visual Studio version 2010

    programming language C#

    browser support

    all browsers supported by RadControls


    PROJECT DESCRIPTION
    A small project that shows how to extend the Caliburn Micro framework to enable the use of a RadWindow as dialog in Caliburn Micro. Be sure to familiarise yourself with the Caliburn.Micro.HelloWindowManager sample project first. 

    I started by extending the IWindowManager manager by adding a method for calling RadWindows:

    /// <summary>
    /// Shows a RadWindow modal dialog for the specified model.
    /// </summary>
    /// <param name="rootModel">The root model.</param>
    /// <param name="context">The context.</param>
     void ShowRadWindowDialog(object rootModel, object context = null);

    Then I added an implementation of the method in the WindowManager class:

    /// <summary>
    /// Shows a RadWindow modal dialog for the specified model.
    /// </summary>
    /// <param name="rootModel">The root model.</param>
    /// <param name="context">The context.</param>
    public virtual void ShowRadWindowDialog(object rootModel, object context = null)
    {
        var view = EnsureRadWindow(rootModel, ViewLocator.LocateForModel(rootModel, null, context));
        ViewModelBinder.Bind(rootModel, view, context);
     
        var haveDisplayName = rootModel as IHaveDisplayName;
        if (haveDisplayName != null && !ConventionManager.HasBinding(view, RadWindow.HeaderProperty))
        {
            var binding = new Binding("DisplayName") { Mode = BindingMode.TwoWay };
            view.SetBinding(RadWindow.HeaderProperty, binding);
        }
     
        new RadWindowConductor(rootModel, view);
     
        view.ShowDialog();
    }

    The EnsureRadWindow method implementation:

    protected virtual RadWindow EnsureRadWindow(object model, object view)
            {
                var window = view as RadWindow;
     
                if (window == null)
                {
                    window = new RadWindow { Content = view };
                    window.SetValue(View.IsGeneratedProperty, true);
                }
     
                return window;
            }

    Finally, the RadWindowConductor class that handles the closing and deactivating:

    public class RadWindowConductor
            {
                bool deactivatingFromView;
                bool deactivateFromViewModel;
                bool actuallyClosing;
                readonly RadWindow view;
                readonly object model;
     
                public RadWindowConductor(object model, RadWindow view)
                {
                    this.model = model;
                    this.view = view;
     
                    var activatable = model as IActivate;
                    if (activatable != null)
                        activatable.Activate();
     
                    var deactivatable = model as IDeactivate;
                    if (deactivatable != null)
                    {
                        view.Closed += Closed;
                        deactivatable.Deactivated += Deactivated;
                    }
     
                    var guard = model as IGuardClose;
                    if (guard != null)
                        view.PreviewClosed += PreviewClosed;
                }
     
                void PreviewClosed(object sender, WindowPreviewClosedEventArgs e)
                {
                    if (e.Cancel != null && (bool)e.Cancel)
                        return;
     
                    var guard = (IGuardClose)model;
     
                    if (actuallyClosing)
                    {
                        actuallyClosing = false;
                        return;
                    }
     
                    bool runningAsync = false, shouldEnd = false;
     
                    guard.CanClose(canClose =>
                    {
                        Execute.OnUIThread(() =>
                        {
                            if (runningAsync && canClose)
                            {
                                actuallyClosing = true;
                                view.Close();
                            }
     
                            else e.Cancel = !canClose;
     
                            shouldEnd = true;
                        });
                    });
     
                    if (shouldEnd)
                        return;
     
                    e.Cancel = true;
                    runningAsync = (bool)e.Cancel;
                }
     
                void Closed(object sender, EventArgs e)
                {
                    view.Closed -= Closed;
     
                    if (deactivateFromViewModel)
                        return;
     
                    var deactivatable = (IDeactivate)model;
     
                    deactivatingFromView = true;
                    deactivatable.Deactivate(true);
                    deactivatingFromView = false;
                }
     
                void Deactivated(object sender, DeactivationEventArgs e)
                {
                    if (!e.WasClosed)
                        return;
     
                    ((IDeactivate)model).Deactivated -= Deactivated;
     
                    if (deactivatingFromView)
                        return;
     
                    deactivateFromViewModel = true;
                    actuallyClosing = true;
                    view.Close();
                    actuallyClosing = false;
                    deactivateFromViewModel = false;
                }
            }

    In order to use it, you will need a RadWindow used as a User Control with an associated ViewModel as per the Caliburn Micro conventions. You will need to use the WindowManager instance obtained from the container in the bootstrapper to perform the action:

    Example usage:

    _windowManager.ShowRadWindowDialog(new MyRadViewModel(_windowManager, _eventAggregator));

    Enjoy
    Stefan Buys
  2. Yana
    Admin
    Yana avatar
    4554 posts

    Posted 04 Apr 2011 Link to this post

    Hi Stefan Buys,

    Thank you for sending the project.  You can find your points updated.

    All the best,
    Yana
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. Rayne
    Rayne avatar
    241 posts
    Member since:
    Sep 2010

    Posted 09 Mar 2012 Link to this post

    Thanks for sharing this...it's exactly what I needed.
Back to Top