Click here to Skip to main content
15,896,207 members
Articles / Programming Languages / C#

(Extended) Modal Window in Silverlight

Rate me:
Please Sign up or sign in to vote.
4.27/5 (6 votes)
2 Apr 2009CPOL3 min read 38.3K   311   19  
An extension of the code submitted in the article: "Modal Window in Silverlight". This extension wraps the hosted control in a window frame that provides various modal features.
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;

namespace ProModel.ApplicationFramework.Silverlight
{
    #region ModalHost Class

    internal class ModalHost : UserControl
    {
        #region Fields/Properties

        protected Size _hostSize;
        protected Canvas _backgroundCanvas;
        protected bool _bMouseCapturing = false;
        protected Point _oLastMousePos = new Point();
        internal IModal _modal;

        public Canvas BackgroundCanvas
        {
            get { return _backgroundCanvas; }
            set { _backgroundCanvas = value; }
        }

        public UserControl ChildControl { get { return _modal.HostedControl; } }

        #endregion

        #region Construction

        public ModalHost()
        {
        }

        public ModalHost(IModal control, bool useCanvasPainting)
        {
            _modal = control;
            _backgroundCanvas = new Canvas();
            _backgroundCanvas.Background
                = (useCanvasPainting) ? new SolidColorBrush(Color.FromArgb(100, 0, 0, 0)) : new SolidColorBrush(Colors.Transparent);
            _backgroundCanvas.Children.Add(_modal as UIElement);
            _modal.HostedControl.Height = _backgroundCanvas.Height;            
            Content = _backgroundCanvas;
            Application.Current.Host.Content.Resized += OnHostResized;

            Loaded += OnHostLoaded;
        }

        #endregion

        #region Method Declarations
        
        public virtual void Close()
        {
            Application.Current.Host.Content.Resized -= OnHostResized;
            Loaded -= OnHostLoaded;
            _modal.HostedControl.MouseLeftButtonDown -= OnMouseLeftButtonDown;
            _modal.HostedControl.MouseLeftButtonUp -= OnMouseLeftButtonUp;
            _modal.HostedControl.MouseMove -= OnMouseMove;
            _backgroundCanvas.Children.Clear();
        }

        protected virtual void OnHostLoaded(object sender, RoutedEventArgs e)
        {
            _modal.HostedControl.MouseLeftButtonDown += OnMouseLeftButtonDown;
            _modal.HostedControl.MouseLeftButtonUp += OnMouseLeftButtonUp;
            _modal.HostedControl.MouseMove += OnMouseMove;

            _modal.HostedControl.Focus();
            _modal.HostedControl.TabNavigation = KeyboardNavigationMode.Cycle;

            // Resize background canvas
            // ----------------------------------------
            _backgroundCanvas.Width = WindowHelpers.GetControlSize(_modal as Control).Width;
            _backgroundCanvas.Height = WindowHelpers.GetControlSize(_modal as Control).Height;

            OnHostResized(null, EventArgs.Empty);
            CentreWindow();
        }

        protected virtual void OnHostResized(object sender, EventArgs e)
        {
            _hostSize.Width = Application.Current.Host.Content.ActualWidth;
            _hostSize.Height = Application.Current.Host.Content.ActualHeight;

            // Resize background canvas
            // ----------------------------------------
            //_backgroundCanvas.Width = _oHostSize.Width;
            //_backgroundCanvas.Height = _oHostSize.Height;

            // not ideal, but wtf?
            _backgroundCanvas.Width = _hostSize.Width;
            _backgroundCanvas.Height = _hostSize.Height;
            CentreWindow();
        }

        public virtual void CentreWindow()
        {
            UserControl modal = _modal as UserControl;

            if (_modal != null && !double.IsNaN(WindowHelpers.GetControlSize(modal).Width) 
                && !double.IsNaN(WindowHelpers.GetPanelSize(_backgroundCanvas).Width))
                modal.SetValue(Canvas.LeftProperty, ((WindowHelpers.GetPanelSize(_backgroundCanvas).Width -
                    WindowHelpers.GetControlSize(modal).Width) / 2));

            if (_modal != null && !double.IsNaN(WindowHelpers.GetControlSize(modal).Height) 
                && !double.IsNaN(WindowHelpers.GetPanelSize(_backgroundCanvas).Height))
                modal.SetValue(Canvas.TopProperty, ((WindowHelpers.GetPanelSize(_backgroundCanvas).Height -
                    WindowHelpers.GetControlSize(modal).Height) / 2));
        }

        #endregion

        #region Dragging code

        protected virtual void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            _bMouseCapturing = _modal.HostedControl.CaptureMouse();
            _oLastMousePos = e.GetPosition(null);
        }

        protected virtual void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _modal.HostedControl.ReleaseMouseCapture();
            _oLastMousePos = new Point();
            _bMouseCapturing = false;
        }

        protected virtual void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (_bMouseCapturing)
            {
                Point oCurrentMousePos = e.GetPosition(null);
                UserControl modal = _modal as UserControl;

                double dblX = (double)modal.GetValue(Canvas.LeftProperty)
                    + oCurrentMousePos.X - _oLastMousePos.X;

                double dblY = (double)modal.GetValue(Canvas.TopProperty)
                    + oCurrentMousePos.Y - _oLastMousePos.Y;

                if (dblX > 0 && dblX + _modal.HostedControl.ActualWidth < _hostSize.Width)
                    modal.SetValue(Canvas.LeftProperty, dblX);

                if (dblY > 0 && dblY + _modal.HostedControl.ActualHeight < _hostSize.Height)
                    modal.SetValue(Canvas.TopProperty, dblY);

                _oLastMousePos = oCurrentMousePos;
            }
        }
        #endregion
    }

    #endregion
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions