WPF -消息展示(问题记录及解决方案)

 
 
问题描述:系统在Loading页面时,服务端返回系统消息,要进行对话框展示,直接用主线程异步会出现闪退,导致对话框闪退。

解决思路如下:        //定义静态字段,把当前消息,标题,消息类型等都暂存起来,等到主页加载完成时在异步调用展示对话框!!!

       
 
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using ZdfFlatUI;

namespace ZdfFlatUI.Test.Helpers
{
    /// <summary>
    /// 系统消息帮助类
    /// 
    /// </summary>
    public static class ShowMessageHelper
    {
        #region 静态字段

        //暂存消息
        static string _delayMes;
        //暂存消息类型
        static int _delayMesType;
        //暂存消息标题
        static string _delayMesTitle;

        #endregion
        /// <summary>
        /// 展示消息
        /// add by yangxp@20180524
        /// </summary>
        /// <param name="message">消息内容</param>
        /// messageType=0 : 一般消息(显示两秒)
        /// messageType>0 : 对话框消息
        /// <param name="messageType">消息类型 一半来自服务端接口返回的消息类型,要与服务端返回的规则保持一致</param>
        /// <param name="title">消息标题</param>
        public static void ShowMessage(string message,string title,int messageType= 0)
        {
            if(messageType==0)
            {
                //一般消息,显示两秒
                DispatcherHelper.DispatcherInvoke(() => MessageToolTip.Show(message));
            }
            else
            {
                DispatcherHelper.DispatcherInvoke(() => ShowMessageBox(message, title, messageType));
            }
        }
        /// <summary>
        /// 打开对话框
        /// </summary>
        /// <param name="message"></param>
        /// <param name="messageType"></param>
        /// <param name="title"></param>
        public static void ShowMessageBox(string message, string title, int messageType)
        {
            if (messageType > 5)
                return;

            //如果当前首页不为主页,则暂存消息信息,在主页的Loaded事件完成后再调用ShowMessageBox()
            Window top = Application.Current.Windows[Application.Current.Windows.Count - 1];
            //if ((topWindow is  LoginWindow || topWindow is LoadingWindow) )
            if (!(top is MainWindow))
            {
                _delayMes = message;
                _delayMesType = messageType;
                _delayMesTitle = title;
                return;
            }

            if (messageType == 0)
            {
                ZMessageBox.Show(message, EnumPromptType.Info);
            }
            else if (messageType == 1)
            {
                ZMessageBox.Show(message, EnumPromptType.Warn);
            }
            else if (messageType == 2)
            {
                ZMessageBox.Show(message, EnumPromptType.Success);
            }
            else if (messageType == 3)
            {
                Window topWindow = Application.Current.Windows[Application.Current.Windows.Count - 1];//获取当前主窗口
                ZMessageBox.Show(Window.GetWindow(topWindow), "您目前使用的浏览器版本过低,可能导致产品部分功能无法正常使用", "", MessageBoxButton.YesNoCancel, EnumPromptType.Warn);
            }
            else
            {
                if (ZMessageBox.Show(message, title, EnumPromptType.Error) == MessageBoxResult.OK)
                {
                    MessageBox.Show("点击了OK");
                }
            }

        }

        //注意:可能出现一种情况,当当前主页不为要展示的主页时(可能为登录页面或者加载页面)服务端返回消息要展示,这时如果直接展示可能出现闪退,特别是为对话框时这个问题尤为显著,解决思路如下:
        //定义静态字段,把当前消息,标题,消息类型等都暂存起来,等到主页加载完成时在异步调用展示对话框!!!
        /// <summary>
        /// 延时调用
        /// 调用方式: DispatcherHelper.DispatcherInvoke(() => ShowMessageBox());
        /// </summary>
        public static void ShowMessageBox()
        {
            if (string.IsNullOrWhiteSpace(_delayMes))
                return;
            string mes = _delayMes;
            string title = _delayMesTitle;
            int type = _delayMesType;
            ShowMessageBox(mes, title, type);
            _delayMes = null;
            _delayMesTitle = null;
            _delayMesType = 0;
        }
    }
}



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

namespace ZdfFlatUI.Test.Helpers
{
    public static class DispatcherHelper
    {
        /// <summary>
        /// 主线程异步执行方法
        /// </summary>add by yangxp@20180524
        /// <param name="method">要执行的方法</param>
        public static void DispatcherInvoke(Action method)
        {
            //获取当前AppDomain对象的Application对象
            System.Windows.Application app = Application.Current;
            if (app != null)
                app.Dispatcher.BeginInvoke(method);
        }
    }
}


猜你喜欢

转载自blog.csdn.net/qq_23018459/article/details/80438699
WPF
今日推荐