zoukankan      html  css  js  c++  java
  • 简化版“询问用户是否退出”

       这篇是 Windows Phone 自定义弹出框和 Toast 通知 的简化版,区别就是之前的自定义 MessageBox

    控件是整个 app 中所有页面共享的,下面的简化版 MessageBox 只是应用于 MainPage 页面中,“询问

    用户是否退出”的自定义弹出框。

         在应用或游戏程序中,经常的一个场景就是在用户点击 Back 键时,应用询问用户是否退出,通常是重写

    Page 页面的事件:

     protected override async void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)

    但是,当弹出 MessageBox 10秒钟用户没有响应,应用则会退出,其实并不是 MessageBox 的 Bug,只要阻塞

    OnBackKeyPress() 方法超过 10秒 ,应用都会退出的,如果先调用 e.Cancle = true 取消导航,再询问用户

    是否退出,就不会出现这个问题。如果用户点击“确定”,则调用   App.Current.Terminate(); 结束当前应用进程。

     一种简单的方式是:

            protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
            {
                e.Cancel = true;
    
                this.Dispatcher.BeginInvoke(delegate 
                {
                    if (MessageBox.Show("确定退出?", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        App.Current.Terminate();
                    }
                });
    
                base.OnBackKeyPress(e);
            }

    另一种方式:

       为了解决这个问题,方式之一就是自定义一个 MessageBox 控件:

       页面的交互如下图:

    第一步:自定义一个名为 MyDialog 的用户控件,页面的主要 xaml:

            <Grid  x:Name="gridDialog" Background="#33000000">
                <Grid Height="280" x:Name="gridBox" VerticalAlignment="Top" Background="#ff1ba0e1">
                    <Grid.Projection>
                        <PlaneProjection/>
                    </Grid.Projection>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="60"/>
                        <RowDefinition Height="150"/>
                        <RowDefinition Height="70"/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="提示信息" x:Name="txtTitle" FontSize="25" Margin="25,10, 0, 0"/>
                    <!--该控件的 Content 属性的内容值可以是字符串或者其它 UIElement-->
                    <ContentControl HorizontalAlignment="Left" FontSize="30" Margin="40, 0, 0, 0" 
    Content
    ="文本内容文本" Grid.Row="1" x:Name="contentContainer"/>
    <StackPanel Grid.Row="2" Orientation="Horizontal"> <Button x:Name="btnOk" Content="OK" Width="200" Click="btnOk_Click"/> <Button x:Name="btnCancle" Content="Cancel" Width="200" Click="btnCancle_Click"/> </StackPanel> </Grid> </Grid>


    自定义弹出框相应的 C# :

       public partial class MyDialog : UserControl
        {
            public MyDialog()
            {
                InitializeComponent();
    
                gridDialog.Visibility = System.Windows.Visibility.Collapsed;
    
                // 把第一个实例赋值给全局静态对象
                if (_instance == null)
                    _instance = this;
            }
    
            //用来控制异步线程中 弹出框 结果返回的时机
            private static AutoResetEvent myResetEvent = new AutoResetEvent(false);
    
            static MessageBoxResult messageBoxResult;
    
            //用一个单一实例,使得应用中的所有页面使用同一个实例
            static MyDialog _instance;
            static MyDialog Instance
            {
                get
                {
                    //if (_instance == null)
                    //    _instance = new MyDialog();
    
                    return _instance;
                }
            }
    
            /// <summary>
            /// 显示包含指定文本、标题栏标题和响应按钮的消息框
            /// </summary>
            /// <param name="messageBoxText">要显示的消息</param>
            /// <param name="caption">消息框的标题</param>
            /// <param name="button">一个值,用于指示要显示哪个按钮或哪些按钮</param>
            /// <returns>一个值,用于指示用户对消息的响应</returns>
            public static Task<MessageBoxResult> Show(string messageBoxText, string caption, MessageBoxButton button)
            {
                return Task<MessageBoxResult>.Factory.StartNew(() =>
                {
                    Instance.Dispatcher.BeginInvoke(delegate
                    {
    
                        Instance.gridDialog.Visibility = Visibility.Visible;
    
                        Instance.contentContainer.Content = messageBoxText;
    
                        Instance.txtTitle.Text = caption;
    
                        if (button == MessageBoxButton.OKCancel)
                        {
                            Instance.btnCancle.Visibility = Visibility.Visible;
                        }
                        else
                        {
                            Instance.btnCancle.Visibility = Visibility.Collapsed;
                        }
    
                        //Instance.UpdateLayout();
    
                        Instance.ShowMessageBoxSB.Stop();
                        Instance.ShowMessageBoxSB.Begin();
                    });
    
    
                    myResetEvent.WaitOne();
    
                    return messageBoxResult;
                });
            }
    
            private void btnOk_Click(object sender, RoutedEventArgs e)
            {
                txtTitle.Text = "";
                contentContainer.Content = null;
    
                gridDialog.Visibility = System.Windows.Visibility.Collapsed;
    
                messageBoxResult = MessageBoxResult.OK;
    
                // 使异步线程的 Show() 方法继续执行
                myResetEvent.Set();
            }
    
            private void btnCancle_Click(object sender, RoutedEventArgs e)
            {
                txtTitle.Text = "";
                contentContainer.Content = null;
    
                gridDialog.Visibility = System.Windows.Visibility.Collapsed;
    
                messageBoxResult = MessageBoxResult.Cancel;
    
                myResetEvent.Set();
            }
    
    
    
            // 用来控制当弹出框显示的时候,如果用户点击 Back 按键,则隐藏弹出框,
            // 在 App.xaml.cs 中的 RootFrame_Navigating 事件中调用
            public static bool DialogIsOpen
            {
                get
                {
                    if (Instance != null && Instance.gridDialog.Visibility == Visibility.Visible)
                    {
                        Instance.btnCancle_Click(null, null);
    
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
        }

    第二步:在 MainPage.xaml 页面中,添加如下代码:

     <local:MyDialog Grid.RowSpan="2"  xmlns:local="clr-namespace:SimpleDialogDemo"/>


    在相应的 C# 页面,重写 OnBackKeyPress 方法:

          protected override async void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
          {
              // 首先取消默认 Back 键关闭应用
              e.Cancel = true;
    
              // 如果 MainPage 页面中,弹出了其它的弹出框,关闭它,
              // 在 DialogIsOpen 属性中实现
              if (MyDialog.DialogIsOpen)
              {
                  //可以做其它事情
              }
              else
              {
                  if (MessageBoxResult.OK == await MyDialog.Show("确定要退出吗?", "温馨提示:", MessageBoxButton.OKCancel))
                  {
                      //  终止当前应用程序。该方法是在 WP8 中加入的,WP7 中木有
                      App.Current.Terminate();
                  }
              }
    
              base.OnBackKeyPress(e);
          }

    代码工程下载

  • 相关阅读:
    C语言编程 两种方法打印一个菱形(渐入显示)
    Java编程格式输出中 printf 的使用实例
    C语言编程输入一个5位数以内的正整数,完成以下操作
    C语言编程判断两个矩阵是否相等(n阶矩阵)
    C语言编程输出100到200的素数的两种方法,和三步优化(逐步优化)
    Java编程中Math.random()的应用(随机生成数的应用)
    C语言编程求1X2X3····Xn所得的数末尾有多少个零
    C语言大数的阶乘
    maven构建一个简单的springboot项目
    nginx的配置
  • 原文地址:https://www.cnblogs.com/hebeiDGL/p/3316195.html
Copyright © 2011-2022 走看看