WPF 10天修炼 第三天- Application全局应用程序类
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了WPF 10天修炼 第三天- Application全局应用程序类,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含16221字,纯文字阅读大概需要24分钟。
内容图文
Application对象
当一个WPF应用程序启动时,首先会实例化一个全局唯一的Application对象,类似于WinForm下的Application类,用于控制整个应用程序,该类将用于追踪应用程序打开的窗口。在应用程序打开或关闭的时候能够触发相应的事件。
创建Application对象
手动创建Application应用程序对象过程:
1、 使用VS创建WPF应用程序,命名为WPFDemo。然后手动清除App.xaml文件。
2、 添加Startup.cs类,并添加程序代码。如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using System.Windows; //添加windows命名空间
namespace WPFDemo
{
???? public class Startup
???? {
???????? [STAThread]
???????? public static void Main()
???????? {
???????????? Application app =? new Application(); //创建application对象
???????????? MainWindow win =? new MainWindow(); //实例化窗口对象,作为应用程序主窗口
???????????? win.Title =? "应用程序主窗口" ; //指定应用程序窗口标题
???????????? app.Run(win); //调用Run方法开始运行应用程序
???????? }
???? }
}
|
3、 F5启动应用程序。
关闭应用程序
Application类提供了一个ShutdownMode的枚举属性值,可以供开发人员指定应用程序的关闭模式。开发人员可以在Application的OnStartup事件为这个属性赋值,也可以在XAML文件中设置这个属性。
ShutdownModel 枚举值
枚举值 |
说明 |
OnLastWindoClose |
当最后一个窗口关闭或在调用Application.Shutdown方法时,应用程序将关闭。 |
OnMainWindowClose |
主窗口关闭或者调用Application.Shutdow方法时,应用程序关闭。 |
OnExplicitShutdown |
即使所有窗口都被关闭,应用程序也不会终止。这个方法适用于一些长时间运行后台任务的场合。当显式调用Application.Shutdown方法后,应用程序才会退出。 |
Application类OnStartup事件中设置ShutdownMode枚举值。
1 2 3 4 5 |
protected override void OnStartup(StartupEventArgs e)
{
?? base .OnStartup(e);
?? this .ShutdownMode = ShutdownMode.OnMainWindowClose;
}
|
App.xaml中指定的ShutdownMode值
1 2 3 4 5 6 7 8 9 10 |
<Application x:Class= "WPFDemo.App"
????????????? xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????????????? xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml"
????????????? xmlns:local= "clr-namespace:WPFDemo"
????????????? StartupUri= "MainWindow.xaml"
???????????? ShutdownMode= "OnLastWindowClose" >
???? <Application.Resources>
???? </Application.Resources>
</Application>???
|
应用程序事件
应用程序执行将会按照顺序触发下列事件。
1、 Startup:应用程序启动事件。
2、 Activated:当应用程序的顶层窗口被激活时触发此事件。
3、 Deactiveated:当应用程序的顶层窗口失去焦点时触发此事件。
4、 DispatherUnhandledException:当应用程序的产生未处理异常时触发此事件。
5、 SessionEnding:当Windows会话被终止时触发此事件,例如用户注销或关闭计算机。
6、 Exit:当应用程序因为某种原因而被关闭时触发此事件。
Startup 应用程序启动事件
该事件在Run方法被调用后触发,这个事件通常用于放置应用程序范围的初始化信息。获取和设置应用程序范围的配置,处理命令行参数等。该事件提供了StartupEventArgs类型的参数,包含了命令行参数信息。
Startup事件可以完成下列任务。
(1)、处理命令行参数。
(2)、打开主窗口。
(3)、初始化应用程序范围的资源。
(4)、初始化应用程序范围的属性。
Startup事件,首先在App.xaml文件中,去掉StartupUri属性,关联Startup事件处理器。
1 2 3 4 5 6 7 8 9 |
<Application x:Class= "WPFDemo.App"
????????????? xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????????????? xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml"
????????????? xmlns:local= "clr-namespace:WPFDemo"
???????????? Startup= "Application_Startup" >
???? <Application.Resources>
???? </Application.Resources>
</Application>
|
接下来在 App.xaml.cs 文件中添加下列事件处理器
1 2 3 4 5 |
private void Application_Startup( object sender, StartupEventArgs e)
{
MainWindow win =? new WPFDemo.MainWindow();
win.Show();
}
|
在实际项目开发中,OnStartup中的代码可以非常复杂,可以读取应用程序资源或读取应用程序设置中读取配置信息,配置参数等。
Activated和Deactiveated事件
应用程序的激活与Window的激活和取消激活类似,但应用程序的激活通常是指全局应用程序的激活,通常发生在如下情况下:
1、 应用程序打开第一个窗口。
2、 用户使用Alt+Tab组合件或者使用任务管理器切换到该应用程序。
3、 用户单击应用程序中一个窗口的任务栏按钮。
与窗口不同的是,一旦应用程序激活,在应用程序停用前都不会再次引发Activated事件。
在上面示例中新增一个名为Window2.xaml的窗口。并修改OnStartup事件处理器的代码,使其启动时能够显示两个窗口。
1 2 3 4 5 6 7 8 9 10 |
private void Application_Startup( object sender, StartupEventArgs e)
{
MainWindow win =? new WPFDemo.MainWindow();
win.Title =? "通过OnStartup事件启动的主窗口" ;
win.Show();
Window2 win2 =? new Window2();
win2.Title =? "通过OnStartup时间启动的第二个窗口" ;
win.Show();
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//重载OnActivated事件,在窗体被激活时触发。
?? protected override void OnActivated(EventArgs e)
?? {
?????? System.Diagnostics.Debug.Write( "当前应用程序被激活" );
?????? foreach (Window win? in Windows)
?????? {
?????????? if (win.IsActive)
?????????? {
?????????????? System.Diagnostics.Debug.WriteLine( "当前的活动窗口是:" + win.Title);
?????????? }
?????? }
?????? base .OnActivated(e);
?? }
|
1 2 3 4 5 6 |
//重载OnDeactivated事件,在窗体被取消激活时触发。
? protected override void OnDeactivated(EventArgs e)
? {
????? base .OnDeactivated(e);
????? System.Diagnostics.Debug.WriteLine( "当前应用程序停止激活" );
? }
|
DispatherUnhandledException事件
DispatcherUnhandledException 给开发人员一个处理应用程序为处理的异常的地方。在window1.xaml.cs 的构造函数中抛出一个异常。
1 2 3 4 5 |
public Window1()
{
InitializeComponent();
throw new Exception( "演示DispatherUnhandledException的作用,这里抛出一个异常" );
}
|
然后在App.xaml中添加对DispatherUnhandledException属性的赋值,最后在App.xaml.cs中添加一些代码来显示一个自定义的错误窗口。
1 2 3 4 5 6 |
private void Application_DispatcherUnhandledException( object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
?? {
?????? string err =? "异常信息:" + e.Exception.Message.ToString();
?????? MessageBox.Show(err);
?????? e.Handled =? true ;
?? }
|
运行应用程序将会弹出下面对话框
SessionEnding事件 – 注销或关闭系统
当Windows操作系统的会话终止时,则会触发SessionEnding事件。SessionEnding事件有一个SessionEndingCancelEventArgs类型的参数,该参数有一下Cancel布尔属性,当设置为true时,将会取消windows的会话终止行为。除此之外,还可以使用ReasonSessionEnding枚举类型的属性,来检测终止会话的类型,该属性有下面两个值:
1、 Logoff :会话正在结束的原因是用户正在注销。
2、 Shutdown : 会话正在结束的原因是用户正在关闭Windows。
下面演示如何使用SessionEnding事件,当windows应用程序终止时,弹出一个对话框窗口提示用户进行选择。
App.xaml 文件制定SessionEnding事件
1 2 3 4 5 6 7 8 9 10 11 |
<Application x:Class= "WPFDemo.App"
????????????? xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????????????? xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml"
????????????? xmlns:local= "clr-namespace:WPFDemo"
????????????? Startup= "Application_Startup"
????????????? SessionEnding= "Application_SessionEnding"
????????????? >
???? <Application.Resources>
???? </Application.Resources>
</Application>
|
在App.xaml.cs文件中添加如下代码
1 2 3 4 5 6 7 8 9 10 |
private void Application_SessionEnding( object sender, SessionEndingCancelEventArgs e)
??? {
??????? //询问用户是否允许终止会话
??????? string msg =? string .Format( "{0} 是否要终止Windows会话?" , e.ReasonSessionEnding);
??????? MessageBoxResult result = MessageBox.Show(msg,? "Session Ending" , MessageBoxButton.YesNo);
??????? if (result == MessageBoxResult.No)
??????? { //如果点击yes,允许终止,否则禁止终止会话
??????????? e.Cancel =? true ;
??????? }
??? }
|
运行应用程序,当windows终止会话时,应用程序会弹出如下图的对话框,如果用户点击“取消”按钮,则会取消终止Windows会话。
Exit事件
当应用程序退出时,将触发Exit事件。下面演示应用程序退出时,向用户隔离区写入应用程序日志和应用程序状态。首先在App.xaml代码中添加事件处理器声明
App.xaml文件
<Application x:Class= "WPFDemo.App"
????????????? xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????????????? xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml"
????????????? xmlns:local= "clr-namespace:WPFDemo"
????????????? Startup= "Application_Startup" DispatcherUnhandledException= "Application_DispatcherUnhandledException"
????????????? SessionEnding= "Application_SessionEnding"
????????????? Exit= "Application_Exit"
????????????? >
???? <Application.Resources>
???? </Application.Resources>
</Application>
|
在App.xaml.cs文件中添加如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
/// <summary>
/// 应用程序退出标志
/// </summary>
public enum ApplicationExitCode
{
???? Success = 0,
???? Failure = 1,
???? CantWriteToApplicationLog = 2,
???? CantPersistApplicationState = 3
}
/// <summary>
/// 应用程序退出
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Application_Exit( object sender, ExitEventArgs e)
{
???? try
???? {
???????? if (e.ApplicationExitCode == ( int )ApplicationExitCode.Success)
???????? {
???????????? WriteApplicationLogEntry( "Failure" , e.ApplicationExitCode);
???????? }
???????? else
???????? {
???????????? WriteApplicationLogEntry( "Success" , e.ApplicationExitCode);
???????? }
???? }
???? catch
???? {
???????? //写入应用程序失败时,更新退出代码已反映出写入失败
???????? e.ApplicationExitCode = ( int )ApplicationExitCode.CantWriteToApplicationLog;
???? }
???? //保存应用程序状态
???? try
???? {
???????? PersistApplicationState();
???? }
???? catch
???? {
???????? //写入应用程序失败时,更新退出代码已反映出写入失败
???????? e.ApplicationExitCode = ( int )ApplicationExitCode.CantPersistApplicationState;
???? }
}
/// <summary>
/// 记录应用程序日志
/// </summary>
/// <param name="message"></param>
/// <param name="exitCode"></param>
private void WriteApplicationLogEntry( string message,? int exitCode)
{
???? //写入日志项到用户隔离存储区
???? IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly();
???? using (Stream stream =? new IsolatedStorageFileStream( "log.txt" , FileMode.Append, FileAccess.Write, store))
???? {
???????? using (StreamWriter writer =? new StreamWriter(stream))
???????? {
???????????? string entry =? string .Format( "{0}:{1} - {2}" , message, exitCode, DateTime.Now);
???????????? writer.WriteLine(entry);
???????? }
???? }
}
/// <summary>
/// 记录应用程序状态日志
/// </summary>
private void PersistApplicationState()
{
???? //保存应用程序状态到用户隔离存储区
???? IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly();
???? using (Stream stream =? new IsolatedStorageFileStream( "state.txt" , FileMode.Create, store))
???? using (StreamWriter writer =? new StreamWriter(stream))
???? {
???????? //可以在这里更改为自定义的保存应用程序状态的程序代码
???????? foreach (DictionaryEntry entry? in this .Properties)
???????? {
???????????? writer.WriteLine(entry.Value);
???????? }
???? }
}
|
上面代码中,首先定义一个推出的枚举类型。在应用程序Exit事件触发,根据不同的推出写入不同的信息到用户的隔离存储区。通常在Exit事件中保存应用程序的配置信息,当应用程序启动时可以在Startup加载配置信息。
Application类的任务
处理命令行参数
在WPF应用程序中,可以使用两种方法来处理命令行参数。一种是通过Environment对象的静态GetCommandLineArgs方法,另一种是通过相应Application类的Startup事件。该事件提供了SartupEventArgs类型的参数,该参数中包含了从命令行提示符或桌面传递的命令行参数。
使用Startup中 StartupEventArgs获取命令行参数
在App.xaml中指定Startup=”Application_Startup”事件,并在App.xaml.cs Startup事件中添加下列代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
private void Application_Startup( object sender, StartupEventArgs e)
{
???? //该bool值将从命令行参数中获取。如果制定了特定的命令行参数,则将该bool值设置为true;
???? bool startMinimized =? false ;
???? //命令行参数是一个字符串数组类型,遍历参数数组,寻找特定的命令行参数。
???? for ( int i = 0; i < e.Args.Length; i++)
???? {
???????? if (e.Args[i] ==? "/StartMinimized" )
???????? {
???????????? startMinimized =? true ;
???????? }
???? }
???? //创建应用程序主窗口,如果指定了命令行参数,则最小化运行应用程序。并在窗口显示第一个命令行参数。
???? Window1 win =? new Window1();
???? if (startMinimized)
???? {
???????? win.WindowState = WindowState.Minimized;
???????? win.Content =? "当前命令行参数" + e.Args[0];
???? }
???? win.Show();
}
|
下面在项目中设置命令行参数来调试应用程序。首先在项目名称点击【右键】选择【属性】【调试】然后再命令行参数设置/StartMinimized。(如下图)然后启动应用程序发现应用程序以最小化方式运行,并且在窗体中显示“当前命令行参数/StartMinimized”
也可以使用CMD命令加参数的方式启动应用程序(如下图):
1、 打开CMD命令窗口。
2、 使用cd命令进入应用程序所在的文件夹。 命令: cd 目录名称
3、 然后执行exe应用程序,并指定参数。命令:WPFDemo.exe /StartMinimized
使用Environment的GetCommandLineArgs方法获取命令行参数
只需要将上面代码中获取参数部分替换为
string[] args = Environment.GetCommandLineArgs();
完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
private void Application_Startup( object sender, StartupEventArgs e)
{
???? //该bool值将从命令行参数中获取。如果制定了特定的命令行参数,则将该bool值设置为true;
???? bool startMinimized =? false ;
???? ///使用Environment的GetCommandLineArgs方法获取命令行参数
???? string [] args = Environment.GetCommandLineArgs();
???? //命令行参数是一个字符串数组类型,遍历参数数组,寻找特定的命令行参数。
???? foreach ( string arge? in args)
???? {
???????? if (arge ==? "/StartMinimized" )
???????? {
???????????? startMinimized =? true ;
???????? }
???? }
???? //创建应用程序主窗口,如果指定了命令行参数,则最小化运行应用程序。并在窗口显示第一个命令行参数。
???? Window2 win =? new Window2();
???? if (startMinimized)
???? {
???????? win.WindowState = WindowState.Minimized;
???????? win.Content =? "当前命令行参数" + e.Args[0];
???? }
???? win.Show();
}
|
单实例应用程序
一个WPF应用程序可以被打开多次,并产生多个进程。在很多场景下只能允许运行一个应用程序。下面提供两种方式创建单实例的应用程序
1、 使用System.Threading命名空间中的Mutex,称为同步基元或者互斥元。
2、 使用windowsFormsApplicationBase类实现单实例应用程序。
使用System.Threading命名空间的Mutex创建单实例应用程序。
1、 引用System.Threading命名空间,定义Mutex对象。
2、 重载Startup方法
3、 运行两个WPF应用程序会弹出“已存在一个应用程序实例”对话框,并关闭当前应用程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Mutex mutex;
? protected override void OnStartup(StartupEventArgs e)
? {
????? base .OnStartup(e);
????? string mutexName =? "WPFDemo" ;
????? bool CreatedNew;
????? mutex =? new Mutex( true , mutexName,? out CreatedNew);
????? if (!CreatedNew) //如果有存在的实例,则关闭当前实例
????? {
????????? MessageBox.Show( "已存在一个应用程序实例" );
????????? Shutdown();
????? }
? }
|
使用windowsFormsApplicationBase实现单实例应用程序。
1、 添加Microsoft.VisualBasic.dll程序集的引用。
2、 新建SingleApplicationBase类,并添加
Microsoft.VisualBasic 和 Microsoft.VisualBasic.ApplicationServices命名空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
//添加命名空间
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.ApplicationServices;
namespace SingleInstanceWithCommunication
{
???? public class SingleApplicationBase : WindowsFormsApplicationBase
???? {
???????? public SingleApplicationBase()
???????? {
???????????? this .IsSingleInstance =? true ;??? //设置为允许单例模式
???????? }
???????? private App wpfApp;
???????? protected override bool OnStartup(StartupEventArgs eventArgs)
???????? {
???????????? wpfApp =? new App();
???????????? wpfApp.Run();
???????????? return false ;
???????? }
???????? //当有其他应用程序实例化时,则出发此事件,将WPF应用程序中显示一个新的窗口
???????? protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
???????? {
???????????? base .OnStartupNextInstance(eventArgs);
???????????? Console.WriteLine( "启动实例" );
???????? }
???? }
}
|
3、 右键选择App.xaml页面的属性,更改生成操作位Page。
4、 然后再App.xaml.cs中添加代码。重载Onstartup事件,设置启动页面,然后创建应用程序启动的Main方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
protected override void OnStartup(StartupEventArgs e)
{
???? base .OnStartup(e);
???? MainWindow win =? new SingleInstanceWithCommunication.MainWindow();
???? this .MainWindow = win;
???? win.Show();
}
[STAThread]
public static void Main( string [] args)
{
???? SingleApplicationBase sab =? new SingleApplicationBase();
???? sab.Run(args);
}???
|
5、多次启动应用程序,发现同时只能运行一个实例。
内容总结
以上是互联网集市为您收集整理的WPF 10天修炼 第三天- Application全局应用程序类全部内容,希望文章能够帮你解决WPF 10天修炼 第三天- Application全局应用程序类所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。