WPF:构建应用程序

简介: 原文  http://www.cnblogs.com/free722/archive/2011/11/13/2247455.html WPF相关的项目内容包含在App.Xaml和Window1.xaml中,这些文件中包含了相当重要的Application对象和Window对象。

原文  http://www.cnblogs.com/free722/archive/2011/11/13/2247455.html

WPF相关的项目内容包含在App.Xaml和Window1.xaml中,这些文件中包含了相当重要的Application对象和Window对象。

Window类

  Window是传统应用程序的主要元素,用来包含应用程序的内容。WPF Window其实只是一个包装过的Win32窗口。操作系统无法区分具有WPF内容的窗口和具有Win32内容的窗口间的差别,它会以相同的方式在非客户端区域进行渲染。

  Window提供了一种对Win32窗口的直接抽象,其中提供了许多简单的方法和属性。在完成Window初始化后,可以调用Show来显示它,调用Hide让它隐藏,调用Close来完全的关闭它。

  Window通过初始化一个继承自Window类的对象,再调用Show方法来创建任意数量的窗口。它也可以把这些Window指派为子窗口。 子窗口和其他上级窗口一样,但它会随着父窗口的关闭而关闭,随着上级窗口的最小化而最小化,这样的Window叫作非模态对话框。

  把其他窗口变为自己的子窗口的Window,必须把它的子窗口的Owner属性设置为它的引用,但这必须在父窗口显示以后方可。它可通过OwnedWindow属性来枚举它的子窗口。

  当一个Window变为活动(active)或非活动(inactive)状态,相应的Activated及Deactived事件就会被触发。可通过调用Window的Activate方法来强行使一个Window变为活动状态。

  关闭窗口时会触发Closing事件。

Application类

  WPF应用程序里的线程必须跑在单线程单元里(STA)。许多API必须从当前线程调用,如果是从其他线程调用,WPF会抛出一个异常。

  为了避免使用Show方法后,窗口立即退出,需要让应用程序不停的从操作系统分配消息给窗口,直到它关闭为止。这些消息和Win32应用程序所 基于的消息是一样的:WM_PAINT、WM_MOUSEMOVE等等。WPF内部必须处理这些信息才能在Windows上跑起来。在Win32里,你要 写一个消息循环来处理进入的消息,并且把它们传给相应的窗口过程。在WPF里,最容易实现这个任务的办法就是使用 System.Windows.Application类。

使用Application.Run

  Application定义了一个叫作Run的方法,用来保持应用程序一直运行,同时分配适当的消息。

复制代码
[STAThread]
public static void Main()
{
Applicateion app = new application();
MainWindow window = new MainWindow();
window.Show();
app.Run(window);
}
复制代码

  Application定义了StartUri属性,它提供了另一种显示应用程序的第一个窗口的方法,可这样使用:

复制代码
[STAThread]
public static void Main()
{
Applicateion app = new Applicateion();
app.StartupUri = new Uri("MainWindow.xaml", UriKind.Relative);
app.Run();
}
复制代码

WPF应用程序中的Main方法在哪里?

  在VS中创建一个WPF Window应用程序时,生成的工程中没有Main方法,但它还是可以运行。事实上,如果尝试添加Main方法,将会得到一个编译错误。

  从XAML编译应用程序是一个特殊的案例,因为VS赋予了XAML文件一个ApplicateionDefinition的Build Action,这会自动生成Main方法。对于Photo Gallery应用程序来说,这个入口点方法可在App.g.cs里找到:

复制代码
[System.ATAThreadAttribute()]
public static void Main()
{
PhotoGallery.App app = new PhotoGallery.App();
app.InitializeComponent();
app.Run();
}
复制代码

  VS隐藏了这个App.g.cs文件。

如何在WPF应用程序中获得命令行参数?

  通常情况下,WPF应用程序不允许实现Main方法,有两种方法可获得命令行参数:一种是预告定义一个继承自Application类的 XAML,这样就可以手动定义一个带有字符串数组参数的Main方法。另一种方法是在程序的任何地方调用 System.Environment.GetCommandLineArgs,它返回的字符串数组与Main方法中获得的字符串数组相同。

Applicateion类的其他用途

  Application类不只是一个简单的程序入口点及消息分发器。它包含一些用来管理常规应用程序级别的任务的事件、属性和方法。你可以重载 继承自Application类(比如VS生成的App类)的OnEventName方法来处理这些事件,它们包含Startup和Exit、 Activated和Deactivated,甚至还有SessionEnding事件,它是在用户注销或关机时触发的事件,并且可以被取消,你可以通过 ReasonSessionEnding枚举值来了解详细信息。

  因为应用程序通常会有多个窗口,Application定义了一个只读的Windows集合,供你访问所有开关的Window。初始窗口可以通过MainWindow属性来访问,它是个可读写属性,你也可以在任何时候指定任何一个窗口为主窗口。

  默认情况下,所有Window被关闭时,Application就退出了(Run方法在这个时候才最终返回)。但这个行为是可修改的,可设置 ShutdownMode属性为不同的值一实现。如:可以让Application在主窗口退出时退出,而不管其他Window当时的状态。即使所有的 Window都已关闭,你同样可以让Application一直运行,直到显式的调用Shutdown方法才退出。这个行为对于需要在最小化时,把自己放 到Windows通知区域的应用程序非常有用。

  Propertied集合是Application类中一个非常方便的属性。Properties很像应用程序状态或者ASP.NET里的会话 状态(session state),它是一个用来存储数据(key/value)的字典,这些数据可以在Window和其他对象之间共享。你只需把数据存储在 Properties集合中就可以了。

  应用程序级别的任务通常在Window的代码中执行,它需要应用程序中不同的Window来获得对于当前应用程序实例的引用。我们可以通过Application.-Current静态属性来访问这个实现。如:

  Application.Current.Properties["CurrentPhotoFilename"] = filename;

如何用WPF创建单实例应用程序

  传统的创建单实例应用程序的方法仍然适用于WPF程序,如使用一个已命名的互斥量(mutex)。代码如下:

复制代码
bool mutexIsNew;
using (System.Threading.Mutex m = new System.Threading.Mutex(true, uniqueName, out mutexIsNew))
{
if(mutexIsNew)
//This is the first instance. Run the application
else
//There is already an instance running. Exit!
}
复制代码

  请确认uniqueName不会被其他应用程序使用!通常,在开发时我们会创建一个GUID来作为标识。

不用Application对象也可以创建应用程序

  不使用Application对象来呈现应用程序是相当容易的,但你需要手动处理消息分发。

  可以使用Win32技术,但WPF同样也在System.Windows.Threading命名空间定义了一个底层的Dispatcher 类,它不用救助于Win32 API就能分发消息。如,你的Main方法可以在呈现主窗口后调用Dispatcher.Run来代替Application.Run(事实 上,Application.Run内部就是用Dispatcher.Run来实现消息分发功能的)。但这样的应用程序仍然缺少其他重要的应用程序管理功 能。如,Dispatcher.Run从不返回,除非你在某处显式的调用Dispatcher.ExitAllFrames。

多线程应用程序

  标准WPF应用程序包含一个UI线程及一个渲染线程(渲染线程不直接提供给开发者,它在后台运行,并且处理像合成这样的底层任务)。可以产生单 独的线程来执行后台工作,但不能从这些线程中直接与UI线程里任何继承自DispatcherObject的对象进行通信。WPF提供了简单的方法,以便 于任何线程可以调度UI线程来运行它们的代码。DispatcherObject定义了Dispatcher属性(Dispatcher类型),它包含了 一些Invoke(同步调用)及BeginInvoke(异步调用)的重载。这些方法会让你传入一个委托,并在dispatcher相应的UI线程上被调 用。所有Invoke与BeginInvoke重载都需要一个DispatcherPriority枚举值。Dispatcher-Priority定义 了10种活动优先级。

  你基至可以在任何产生的线程中通过调用Dispatcher.Run,来为你的应用程序提供多个UI线程。如果你的应用程序有多个顶层Window的话,可以使每个Window运行在一个独立的线程中。

创建并显示对话框

  Windows提供了一些常规对话框(模态子窗口)。

常规对话框

  WPF为常规对话框提供了一些内建的类,这些类通过一些属性和方法提供常规对话框的功能。注意,WPF本身不渲染这些对话框,它是通过内部调用Win32 API来呈现对话框并与它们通信的。

  使用内建对话框的步骤大约为:初始化对话框,调用它的ShowDialog方法,然后处理它的结果。

自定义对话框

  在WPF中,创建使用对话框与创建使用窗口基本相同。事实上,对话框就是窗口,但通常要额外处理返回的对话框结果。

  调用ShowDialog方法显示模态窗口,调用Show方法则显示非模态窗口。ShowDialog是阻塞式调用,并且它返回一个可以为null的Boolean(C#中的bool?类型)。

ShowDialog的另一种用法

  要在允许消息分发的同时获得对话框的阻塞行为,Window的ShowDialog方法会像Application.Run那样调用Dispatcher.Run。所以以下方法可以在不使用Application类的情况下启动WPF Window:

[STAThread]
public static void Main()
{
MainWindow window = new MainWindow();
window.ShowDialog();
}

维持并恢复应用程序状态

  一个标准的Windows应用程序可以拥有对当前计算机的所有访问权限,所以有许多不同的存储数据的方式,如果使用注册表或本地文件系统。但另 一种充满魅力的方法是使用.NET Framework的分离存储技术。除了使用简单以外,它适用于所有能运行托管代码的环境。

目录
相关文章
|
前端开发 Ubuntu Linux
【.NET6+Avalonia】开发支持跨平台的仿WPF应用程序以及基于ubuntu系统的演示
随着跨平台越来越流行,.net core支持跨平台至今也有好几年的光景了。但是目前基于.net的跨平台,大多数还是在使用B/S架构的跨平台上;至于C/S架构,大部分人可能会选择QT进行开发,或者很早之前还有一款Mono可以支持.NET开发者进行开发跨平台应用。
924 0
【.NET6+Avalonia】开发支持跨平台的仿WPF应用程序以及基于ubuntu系统的演示
|
C#
WPF 4 Ribbon 开发 之 应用程序菜单(Application Menu)
原文:WPF 4 Ribbon 开发 之 应用程序菜单(Application Menu)      在上一篇中我们完成了快捷工具栏的开发,本篇将讲解应用程序菜单开发的相关内容。如下图所示,点击程序窗口左上角的记事本图标(Application Button)会显示出应用程序菜单(Application Menu)列表,列表中的按键即为软件的一些基本功能。
2147 0
|
9月前
|
C#
C#开源的虚拟桌宠模拟器,可以内置到任何WPF应用程序 - VPet
C#开源的虚拟桌宠模拟器,可以内置到任何WPF应用程序 - VPet
111 0
|
8月前
|
人工智能 C#
虚拟桌宠模拟器:VPet-Simulator,一个开源的桌宠软件, 可以内置到任何WPF应用程序
虚拟桌宠模拟器:VPet-Simulator,一个开源的桌宠软件, 可以内置到任何WPF应用程序
虚拟桌宠模拟器:VPet-Simulator,一个开源的桌宠软件, 可以内置到任何WPF应用程序
|
C#
4.使用代码和未经编译的XAML创建WPF应用程序
4.使用代码和未经编译的XAML创建WPF应用程序
62 0
|
C# C++ Windows
3.只使用代码创建WPF应用程序
3.只使用代码创建WPF应用程序
84 0
|
XML 存储 数据可视化
能快速构建和定制网络拓扑图的WPF开源项目-NodeNetwork
在现代软件开发中,数据可视化和可交互性越来越受到关注。为了实现这一点,通常需要使用各种图表、表格、网络拓扑图等控件。NodeNetwork就是一种这样的自定义方式,它是一个基于C# WPF的开源项目,可以帮助我们快速构建和定制网络拓扑图。
能快速构建和定制网络拓扑图的WPF开源项目-NodeNetwork
|
C# 虚拟化 UED
细数改善WPF应用程序性能的10大方法
原文:细数改善WPF应用程序性能的10大方法       WPF(Windows Presentation Foundation)应用程序在没有图形加速设备的机器上运行速度很慢是个公开的秘密,给用户的感觉是它太吃资源了,WPF程序的性能和硬件确实有很大的关系,越高档的机器性能越有优势。
1171 0
|
Shell C# Windows
Prism for WPF初探(构建简单的模块化开发框架)
原文:Prism for WPF初探(构建简单的模块化开发框架)   先简单的介绍一下Prism框架,引用微软官方的解释: Prism provides guidance to help you more easily design and build, flexible, and easy-to...
9184 0
|
前端开发 C# 程序员
WPF整理-XAML构建后台类对象
原文:WPF整理-XAML构建后台类对象 1.XAML 接触WPF的第一眼就是XAML---XAML是用来描绘界面的。其实不然! "Actually, XAML has nothing to do with UI. It's merely a declarative way of constructing objects and setting their properties.” XAML和UI一点关系也没有,它仅仅是一种以声明方式来构建对象,设置对象属性的一种方式而已,和code behind file作用差不多。
927 0