Friday, August 2, 2013

Modal Popup & Flyout Popup in WinRT




First I created a child window base class:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;

namespace PopupSample.Bases
{
    public class ChildWindowBase : UserControl, IDisposable
    {
        public ChildWindowBase() : base()
        {

        }

        public Page Opener { get; set; }
        public bool? DialogResult { get; set; }

        public string ChildWindowName
        {
            get { return this.GetType().Name; }
        }

        private static Popup _popup;
        private static Popup _RootPopup;

        [DefaultValue(FlyoutType.Center)]
        public FlyoutType Flyout { get; set; }

        public void Show()
        {
            switch (Flyout)
            {
                //Modal Popup
                case FlyoutType.Center:
                    CenterShow();
                    break;
                case FlyoutType.Left:
                    LeftShow();
                    break;
                case FlyoutType.Top:
                    TopShow();
                    break;
                case FlyoutType.Right:
                    RightShow();
                    break;
                case FlyoutType.Bottom:
                    BottomShow();
                    break;
                default:
                    break;
            }
        }

        private void CenterShow()
        {
            var bounds = Window.Current.Bounds;
            var width = Double.IsNaN(this.Width) ? 900 : this.Width;
            var height = Double.IsNaN(this.Height) ? 550 : this.Height;

            Grid RootPanel = new Grid
            {
                Name = "RootPanel",
                Opacity = 0.60,
                Background = new SolidColorBrush(Colors.White),
                Width = bounds.Width,
                Height = bounds.Height,
                VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Stretch,
                HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Stretch
            };

            _RootPopup = new Popup
            {
                Child = RootPanel
            };

            _popup = new Popup
            {
                ChildTransitions = new TransitionCollection
                                                    {
                                                        new AddDeleteThemeTransition(),
                                                        new PopupThemeTransition {FromVerticalOffset = bounds.Height}
                                                    },
                HorizontalOffset = (bounds.Width / 2) - (width / 2),
                VerticalOffset = (bounds.Height / 2) - (height / 2),
                Child = this,
            };

            _RootPopup.IsOpen = true;
            (Window.Current.Content as Frame).IsEnabled = false;
            _popup.IsOpen = true;

            OnShowCompleted(EventArgs.Empty);
        }

        private void LeftShow()
        {
            var bounds = Window.Current.Bounds;

            var width = Double.IsNaN(this.Width) ? 480 : this.Width;
            (this.Content as FrameworkElement).Height = bounds.Height;

            _popup = new Popup
            {
                ChildTransitions = new TransitionCollection
                                                    {
                                                        new EntranceThemeTransition {FromHorizontalOffset = 0},
                                                    },
                HorizontalOffset = 0,
                IsLightDismissEnabled = true,
                Child = this,
            };

            _popup.IsOpen = true;

            OnShowCompleted(EventArgs.Empty);
        }

        private void TopShow()
        {
            var bounds = Window.Current.Bounds;

            var height = Double.IsNaN(this.Height) ? 200 : this.Height;
            (this.Content as FrameworkElement).Width = bounds.Width;

            _popup = new Popup
            {
                ChildTransitions = new TransitionCollection
                                                    {
                                                        new EntranceThemeTransition {FromVerticalOffset = 0}
                                                    },
                VerticalOffset = 0,
                IsLightDismissEnabled = true,
                Child = this,
            };

            _popup.IsOpen = true;

            OnShowCompleted(EventArgs.Empty);
        }

        private void RightShow()
        {
            var bounds = Window.Current.Bounds;

            var width = Double.IsNaN(this.Width) ? 480 : this.Width;
            (this.Content as FrameworkElement).Height = bounds.Height;

            _popup = new Popup
            {
                ChildTransitions = new TransitionCollection
                                                    {
                                                        new EntranceThemeTransition {FromHorizontalOffset = bounds.Width}
                                                    },
                HorizontalOffset = bounds.Width - width,
                IsLightDismissEnabled = true,
                Child = this,
            };

            _popup.IsOpen = true;

            OnShowCompleted(EventArgs.Empty);
        }

        private void BottomShow()
        {
            var bounds = Window.Current.Bounds;

            var height = Double.IsNaN(this.Height) ? 200 : this.Height;
            (this.Content as FrameworkElement).Width = bounds.Width;

            _popup = new Popup
            {
                ChildTransitions = new TransitionCollection
                                                    {
                                                        new EntranceThemeTransition {FromVerticalOffset = bounds.Height}
                                                    },
                VerticalOffset = bounds.Height - height,
                IsLightDismissEnabled = true,
                Child = this,
            };

            _popup.IsOpen = true;

            OnShowCompleted(EventArgs.Empty);
        }

        public void Close()
        {
            _popup.IsOpen = false;
            (Window.Current.Content as Frame).IsEnabled = true;

            if (Flyout == FlyoutType.Center)
            {
                _RootPopup.IsOpen = false;
            }

            OnClosed(EventArgs.Empty);
        }

        public void OnInitialized()
        {

        }

        public event EventHandler Closed;
        public event EventHandler ShowCompleted;

        protected virtual void OnClosed(EventArgs e)
        {
            if (Closed != null)
                Closed(this, e);
        }

        protected virtual void OnShowCompleted(EventArgs e)
        {
            if (ShowCompleted != null)
                ShowCompleted(this, e);
        }

        #region IDisposable Members

        public virtual async void Dispose()
        {
            try
            {
                await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                {
                    this.Close();
                    this.Content = null;
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


        #endregion
    }

    public enum FlyoutType
    {
        Center,
        Left,
        Top,
        Right,
        Bottom
    }
}
 

For selecting popup type (modal or flyout) I use an enum (FlyoutType) if FlyoutType = Center then the popup is modal else the popup is flyout.


Modal Sample:
XAML:

<bases:ChildWindowBase
    x:Class="PopupSample.ChildWindows.ModalSample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:bases="using:PopupSample.Bases"
    mc:Ignorable="d"
    d:DesignHeight="216"
    d:DesignWidth="384"
    Height="216"
    Width="384">

    <Border BorderThickness="2" BorderBrush="#FF8F8B8B" Background="DarkOrchid" CornerRadius="20">
        <Grid Margin="10">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="50"/>
                </Grid.RowDefinitions>

                <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Center">
                    <Button Width="100" Height="35" Content="Save" Click="btnSave_Click"/>
                    <Button Width="100" Height="35" Content="Cancel" Click="btnCancel_Click"/>
                </StackPanel>
            </Grid>
        </Grid>
    </Border>
</bases:ChildWindowBase>


CS:

using PopupSample.Bases;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;

namespace PopupSample.ChildWindows
{
    public sealed partial class ModalSample : ChildWindowBase
    {
        public ModalSample()
        {
            this.InitializeComponent();

            this.Loaded += ModalSample_Loaded;
        }

        private void ModalSample_Loaded(object sender, RoutedEventArgs e)
        {
            
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
            this.Close();
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
            this.Close();
        }
    }
}

DialogResualt is for returning value into opener window.


Open a modal popup:


ModalSample modal;

private void Modal_Click(object sender, RoutedEventArgs e)
{
    modal = new ModalSample();
    modal.ShowCompleted += modal_ShowCompleted;
    modal.Closed += modal_Closed;

    modal.Show();
}

void modal_ShowCompleted(object sender, EventArgs e)
{
    lstEvents.Items.Add(String.Format("modal_ShowCompleted - {0}", DateTime.Now));
}

void modal_Closed(object sender, EventArgs e)
{
    lstEvents.Items.Add(String.Format("modal_Closed - {0} - Resualt: {1}", DateTime.Now, modal.DialogResult));
}


ShowCompleted Event fire when popup opened successfully.
Closed Event fire when popup closed successfully.



Flyout Sample:

XAML:


<bases:ChildWindowBase
    x:Class="PopupSample.ChildWindows.FlyoutSample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:bases="using:PopupSample.Bases"
    mc:Ignorable="d"
    d:DesignHeight="500"
    d:DesignWidth="384"
    MinWidth="384"
    MinHeight="500"
    Width="384">

    <Border BorderThickness="2" BorderBrush="#FF8F8B8B" Background="#FFDCD6D6">
        
    </Border>
</bases:ChildWindowBase>


CS:

using PopupSample.Bases;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;

namespace PopupSample.ChildWindows
{
    public sealed partial class FlyoutSample : ChildWindowBase
    {
        public FlyoutSample()
        {
            this.InitializeComponent();

            this.Loaded += FlayoutSample_Loaded;
        }

        private void FlayoutSample_Loaded(object sender, RoutedEventArgs e)
        {
            
        }
    }
}


Open a flyout popup:

FlyoutSample flyout;
        
private void Flyout_Click(object sender, RoutedEventArgs e)
{
    flyout = new FlyoutSample { Flyout = Bases.FlyoutType.Right };
    flyout.ShowCompleted += flyout_ShowCompleted;

    flyout.Show();
}

void flyout_ShowCompleted(object sender, EventArgs e)
{
    lstEvents.Items.Add(String.Format("flyout_ShowCompleted - {0}", DateTime.Now));
}




Download full sample from here

No comments:

Post a Comment