C# WPF编程之Application类的使用详解
作者:SongYuLong的博客
应用程序的生命周期
在WPF中,应用程序会经历简单的生命周期。本质上,Visual Studio为Application类使用的模型与用于窗口的模型相同。起点是XAML模板,默认情况下该模板命名为App.xaml:
创建Application对象
<Application x:Class="WpfApp3.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp3" StartupUri="MainWindow.xaml"> <Application.Resources> </Application.Resources> </Application>
StartupUri属性来确定主窗口的XAML文档。因此不需要代码显式地实例化窗口,XAML解析器自动完成这项工作。自动生成的部分在项目中是不可见的,看起来如下:
using System; using System.Windows; public partial class App:Application { [STAThread()] public static void Main() { WpfApp3.App app = new WpfApp3.App(); app.InitializeComponent(); app.Run(); } public void InitializeComponent() { this.StartupUri = new Uri("Window1.xaml", System.UriKind.Relative); } }
应用程序的关闭方式
通常,只要有窗口未关闭,Application类就保持应用程序处于有效状态。
可通过Appliaction.ShutdownMode属性修改关闭模式,枚举值:
- OnLastWindowClose:默认行为,只少有一个窗口存在,应用程序就保持运行状态。
- OnMainWindowClose:传统方式,只要主窗口还处于打开状态,应用程序就保持运行状态。
- OnExplictitShutdown:除非调用Application.Shutdown()方法,否则应用程序不会结束。
App.xaml文件中添加ShutdownMode=“OnMainWindowClose”
<Application x:Class="WpfApp3.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp3" StartupUri="MainWindow.xaml" ShutdownMode="OnMainWindowClose"> <Application.Resources> </Application.Resources> </Application>
应用程序事件
App.xaml.cs文件里可添加代码来处理应用程序事件。
应用程序事件:
- Startup:该事件在调用Application.Run()方法之后,并且在主窗口显示之前。
- Exit:该事件在应用程序关闭时,并在Run()方法即将返回之前发生。
- SessionEnding:该事件在Window对话结束时发生。
- Activated:当激活应用程序中的窗口是发生该事件。
- Deactivated:当取消激活用用程序中的窗口时发生该事件。
- DispatcherUnhandledException:在应用程序中的任何位置,只要发送未处理的异常,就会发生该事件。
- 处理事件两种方法:
- 关联事件处理程序;
重写相应的受保护方法。
关联事件处理程序,如xmal中添加事件处理DispatcherUnhandledException=“Application_DispatcherUnhandledException”
App.xaml
<Application x:Class="WpfApp3.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp3" StartupUri="MainWindow.xaml" DispatcherUnhandledException="Application_DispatcherUnhandledException"> <Application.Resources> </Application.Resources> </Application>
App.xaml.cs:
private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) { }
代码重写事件方法窗口事件:
using System.Configuration; using System.Data; using System.Windows; namespace WpfApp3 { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : Application { private bool unsaveDate = false; public bool UnsaveDate { get { return unsaveDate; } set { unsaveDate = value; } } protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); UnsaveDate = true; } protected override void OnSessionEnding(SessionEndingCancelEventArgs e) { base.OnSessionEnding(e); if (UnsaveDate) { e.Cancel = true; MessageBox.Show("测试:"+e.ReasonSessionEnding.ToString()); } } } }
Application类的任务
显示初始界面
WPF应用程序的运行速度快,但并不能在瞬间启动。第一次启动应用程序时,会有一些延迟,因为公共语言运行时(Common Language Runtime,CLR)首先需要初始化.NET环境,然后启动应用程序。通常这一延时时间很短。但如果具有更耗时的初始化步骤,可使用WPF提供的简单初始界面特性,添加加初始界面的方法:
- 为项目添加图像文件(.bmp,.png,.jpg文件)。
- 在Solution Explorer中选择图像文件。
- 将Build Action修改为SplashScreen。
下次运行应用程序时,图像会立即在屏幕中央显示出来。当添加初始界面时,WPF编译器为自动生成的App.cs文件添加与下面类似的代码:
SplashScreen splashScreen = new SplashScreen("splashScreenImage.png"); splashScreen.show(true); MyApplication.App app = new MyApplication.App(); app.InitializeComponent(); app.Run();
处理命令行参数
为处理命令行参数,需要响应Application.Startup事件。命令行参数是通过StartupEventArgs.Args属性作为字符串数组提供的。
例如,假定希望加载文档,文档名作为命令行参数传递。通过代码实例化主窗口。
public partial class App : Application { private static void App_Startup(object sender, StartupEventArgs e) { FileViewer win = new FileViewer(); if (e.Args.Length > 0) { string file = e.Args[0]; if (System.IO.File.Exists(file)) { win.LoadFile(file); } else { } } } }
访问当前Application对象
通过静态的Application.Current属性,可在应用程序的任何位置获取当前应用程序的实例,从而在窗口之间进行基本交互,任何窗口都可以访问当前Application对象,并通过Application对象获取主窗口的引用:
Window main = Application.Current.MainWindow; MessageBox.Show("The main window is " + main.Title);
如果希望访问在自定义窗口类中添加的任意方法、属性或事件,需要将窗口对象转装换为正确类型。
MainWindow main = (MainWindow)Application.Current.MainWindow; main.DoSomething();
在窗口中还可以检查Application.Windows集合的内容:
foreach( Window window in Application.Current.Windows) { MessageBox.Show(window.Title + " is open."); }
在窗口之间进行交互
应用程序类还可以很好地达到另一个目的:保存重要窗口的引用,使一个窗口可访问另一个窗口。
窗口分为模态和非模态:
- 模态窗口:模态窗口会中断应用程序流,直到窗口关闭为止。
- 非模态窗口:非模态窗口则不中断应用程序流。
示例,每个文档窗口由名为Document的类实例表示:
public partial class App : Application { private List<Document> documents = new List<Document>(); public List<Document> Documents { get {return documents}; set {documents = value;} } }
下面是响应按钮点击事件的处理程序:
private void cmdCreate_Click(object sender, RouteEventArgs e) { Document doc = new Document(); doc.Owner = this; doc.Show(); ((App)Application.Current).Documents.Add(doc); }
程序集资源
WPF应用程序中的程序集资源与其他.NET应用程序中的程序集资源在本质上是相同的。基本概念是为项目添加文件,从二Visual Studio可将其嵌入到编译过的应用程序的EXE或DLL文件中。
添加资源
通过向项目添加文件,并在Properties窗口中将其Build Action属性设置为Resource来添加资源。
为成功地使用程序集资源,未必注意一下两点:
- 不能将Build Action属性错误地设置为Embedded Resource。
- 不要在Project Properties窗口中使用Resource选项卡。
检索资源
可以采用多种方法来使用资源。
低级方法是检索封装数据的StreamResourceInfo对象,然后决定如何使用该对象。
StreamResourceInfo sri = Application.GetResourceStream(new Uri(“images/winter.jpg”, UriKind.Relative));
XMAL:
<\Image Source=“Images/1.jpg”></Image>
使用BitmapImage对象,该对象使用URI确定希望显示的图像位置。
绝对路径:
img.Source = new BitmapImage(new Uri((@“d:\Img\jpgs\2.jpg”));
相对路径:
img.Source = new BitmapImage(new Uri(“images/6.jpg”, UriKind.Relative));
pack URI
WPF使用pack URI语法寻址编译个的资源。使用相对URI来引用资源
内容文件
当嵌入式文件作为资源时,会将文件放到编译过的程序集中,并且可以确保文件总是可用的。
如下情况不适合使用这种方法:
- 希望改变资源文件,有不想重新编译应用程序;
- 资源文件非常大;
- 资源文件是可选的,并且可以不随程序集一起部署;
- 资源是声音文件(WPF声音类不支持程序集资源);
WPF为程序集添加了AssemblyAssociatedContentFile特性,声明每个内容文件的存在。
为项目添加音频文件:
在Solution Explorer中选择该文件,并在Properties中将Build Action属性改为Content。
<\MediaElement Name=“Sound” Source=“Sounds/1.wav” LoadeBehavior=“Manual”></MediaElement>
到此这篇关于C# WPF编程之Application类的使用详解的文章就介绍到这了,更多相关C# Application类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!