C# WPF编程-Application类(生命周期、程序集资源、本地化)

C# WPF编程-Application类

  • 应用程序的生命周期
    • 创建Application对象
    • 应用程序的关闭方式
    • 应用程序事件
  • Application类的任务
    • 显示初始界面
    • 处理命令行参数
    • 访问当前Application对象
    • 在窗口之间进行交互
  • 程序集资源
    • 添加资源
    • 检索资源
    • pack URI
    • 内容文件

每个运行中的WPF应用程序都由System.Windows.Application类的一个实例来表示。该类跟踪在应用程序中打开的所有窗口,决定何时关闭应用程序。

应用程序的生命周期

在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来引用资源
images/2.jpg
等效的绝对URI是:
pack://application:,/images/winter.jpg

使用pack URI还可以检索到另一个库中的资源(即,在应用程序中使用DLL程序集的资源),语法:
pack://application:,/AssemblyName;component/ResourceName
例如,图像被嵌入到引用的名为ImageLibrary的程序集中,使用如下RUI:
img.Source = new BitmapImage(new Uri(“pack://application:,/ImageLibrary;comonent/images/2.jpg”));
或使用相对URI:
img.Source = new BitmapImage(new Uri(“ImageLibrary;component/images/1.jpg”, UriKind.Relative));

如果使用强命名的程序集,可使用包含版本和/或公钥标记的限定程序集引用代替程序集的名称。使用分号隔离每段信息,并在版本号数字前添加字母V,使用版本号的实例:
img.Source = new BitmapImage(new Uri(“ImageLibrary;v1.25;component/images/2.jpg”, UriKind.Relative));

内容文件

当嵌入式文件作为资源时,会将文件放到编译过的程序集中,并且可以确保文件总是可用的。
如下情况不适合使用这种方法:

  • 希望改变资源文件,有不想重新编译应用程序;
  • 资源文件非常大;
  • 资源文件是可选的,并且可以不随程序集一起部署;
  • 资源是声音文件(WPF声音类不支持程序集资源);

WPF为程序集添加了AssemblyAssociatedContentFile特性,声明每个内容文件的存在。
为项目添加音频文件:

  • 在Solution Explorer中选择该文件,并在Properties中将Build Action属性改为Content。
    <MediaElement Name=“Sound” Source=“Sounds/1.wav” LoadeBehavior=“Manual”><MediaElement>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/294559.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp 开发之原生Android插件

开发须知 在您阅读此文档时&#xff0c;我们假定您已经具备了相应Android应用开发经验&#xff0c;使用Android Studio开发过Android原生。也应该对HTML,JavaScript,CSS等有一定的了解, 并且熟悉在JavaScript和JAVA环境下的JSON格式数据操作等。 为了插件开发者更方便快捷的开…

在Windows的Docker上部署Mysql服务

在我们做一些和数据库相关的测试时&#xff0c;往往需要快速部署一个数据库作为数据源。如果开发环境是Windows&#xff0c;且开发的代码不依赖于系统&#xff0c;即不用在linux上做开发&#xff0c;则可以将全套环境都部署在Windows上。 本地安装数据库会污染操作系统环境&…

【学习笔记】java项目—苍穹外卖day03

文章目录 苍穹外卖-day03课程内容1. 公共字段自动填充1.1 问题分析1.2 实现思路1.3 代码开发1.3.1 步骤一1.3.2 步骤二1.3.3 步骤三 1.4 功能测试1.5 代码提交 2. 新增菜品2.1 需求分析与设计2.1.1 产品原型2.1.2 接口设计2.1.3 表设计 2.2 代码开发2.2.1 文件上传实现2.2.2 新…

test02

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

Linux shell编程学习笔记45:uname命令-获取Linux系统信息

0 前言 linux 有多个发行版本&#xff0c;不同的版本都有自己的版本号。 如何知道自己使用的Linux的系统信息呢&#xff1f; 使用uname命令、hostnamectl命令&#xff0c;或者通过查看/proc/version文件来了解这些信息。 我们先看看uname命令。 1 uname 命令的功能和格式 …

Java

1.学生和老师都会有work方法&#xff0c;学生的工作是学习&#xff0c;老师的工作是教书&#xff0c;我利用了一个接口来实现&#xff1b; 2.同时&#xff0c;老师和学生都是人&#xff0c;并且都有姓名&#xff0c;姓名&#xff0c;年龄和身高等特征&#xff0c;我用了一个继承…

加密软件VMProtect教程:使用脚本-功能

VMProtect是新一代软件保护实用程序。VMProtect支持德尔菲、Borland C Builder、Visual C/C、Visual Basic&#xff08;本机&#xff09;、Virtual Pascal和XCode编译器。 同时&#xff0c;VMProtect有一个内置的反汇编程序&#xff0c;可以与Windows和Mac OS X可执行文件一起…

RabbitMQ高级笔记

视频链接&#xff1a;【黑马程序员RabbitMQ入门到实战教程】 文章目录 1.发送者的可靠性1.1.生产者重试机制1.2.生产者确认机制1.3.实现生产者确认1.3.1.开启生产者确认1.3.2.定义ReturnCallback1.3.3.定义ConfirmCallback 2.MQ的可靠性2.1.数据持久化2.1.1.交换机持久化2.1.2.…

Docker搭建LNMP环境实战(09):安装mariadb

1、编写mariadb部署配置文件 在文件夹&#xff1a;/mnt/hgfs/dockers/test_site/compose下创建文件&#xff1a;test_site_mariadb.yml&#xff0c;内容如下&#xff1a; version: "3.5" services:test_site_mariadb:container_name: test_site_mariadbimage: mari…

代码+视频,手动绘制logistic回归预测模型校准曲线(Calibration curve)(1)

校准曲线图表示的是预测值和实际值的差距&#xff0c;作为预测模型的重要部分&#xff0c;目前很多函数能绘制校准曲线。 一般分为两种&#xff0c;一种是通过Hosmer-Lemeshow检验&#xff0c;把P值分为10等分&#xff0c;求出每等分的预测值和实际值的差距. 另外一种是calibra…

vue3源码解析——ref和reactive定义响应式的区别

ref 和 reactive 是 Vue 3.0 中用于定义响应式数据的两个新 API。它们有以下区别&#xff1a; ref 定义单个响应式数据 数据类型可以是任意类型。它通常用于定义原始数据类型为响应式数据。返回一个响应式对象&#xff0c;该对象包含一个 .value 属性&#xff0c;可用于获取和设…

java学习之路-数组定义与使用

目录 ​编辑 1.什么是数组 2.数组的创建及其初始化 2.1数组的创建 2.2数组的初始化 3.数组的使用 3.1数组元素访问 3.2遍历数组 4.数组是引用类型 4.1jvm的内存分布 4.2基本类型变量与引用类型变量的区别 4.3引用变量详解 4.4 null 5.数组的使用场景 5.1存储数据 5…

在jupyter notebook中使用conda环境

在jupyter notebook中使用conda环境 1. 环境配置 conda activate my-conda-env # this is the environment for your project and code conda install ipykernel conda deactivateconda activate base # could be also some other environment conda install nb_cond…

harbor api v2.0

harbor api v2.0 v2.0 v2.0 “harbor api v2.0”与v1区别较大&#xff0c;此处harbor也做了https。另外&#xff0c;通过接口拿到的数据也是只能默认1页10个&#xff0c;所以脚本根据实际情况一页页的循环抓取数据 脚本主要用于统计repo(仓库)、image&#xff0c;以及所有镜像…

什么是智慧公厕?智慧城市下的智慧公厕有什么功能和特点?

随着科技的不断进步和城市化的加快发展&#xff0c;智慧城市已经成为我们生活中的一部分。而在智慧城市的建设中&#xff0c;智慧公厕作为城市基础设施的重要组成部分发挥着重要的作用。那么什么是智慧公厕&#xff1f;智慧公厕是针对公共厕所的日常使用、运行、管理、运营等过…

Python文件操作命令

文件操作 我知道你最近很累&#xff0c;是那种看不见的、身体上和精神上的疲惫感&#xff0c;但是请你一定要坚持下去。就算无人问津也好&#xff0c;技不如人也好&#xff0c;千万别让烦躁和焦虑毁了你的热情和定力。别贪心&#xff0c;我们不可能什么都有&#xff0c;也别灰心…

4月2日 qt密码生成小程序(可选择生成密码的格式),基于Python框架下的pyqt6

4月2日 密码生成小程序 代码展示&#xff1a; import stringfrom PyQt6.QtWidgets import (QApplication, QDialog,QMessageBox ) from untitled import Ui_PasswordGender import sys import string # py模块含有字符 import randomclass MyPasswordGenerate(Ui_Password…

【Vue3源码学习】— CH2.6 effect.ts:详解

effect.ts&#xff1a;详解 1. 理解activeEffect1.1 定义1.2 通过一个例子来说明这个过程a. 副作用函数的初始化b. 执行副作用函数前c. 访问state.countd. get拦截器中的track调用e. 修改state.count时的set拦截器f. trigger函数中的依赖重新执行 1.3 实战应用1.4 activeEffect…

Mysql数据备份与恢复实战

文章目录 备份类型备份内容备份工具mysqldump备份 实战案例&#xff1a;恢复误删除的表准备工作2:30完全备份完全备份后更新数据表10:00误删students表需要恢复还原的状态开始还原恢复 为什么要备份&#xff1f; 备份是为了&#xff1a;灾难恢复&#xff1a;硬件故障、软件故障…

Php_Code_challenge16

题目&#xff1a; 答案&#xff1a; 解析&#xff1a; 所以科学计数法绕过即可。