WPF:构建应用程序
原文 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的分离存储技术。除了使用简单以外,它适用于所有能运行托管代码的环境。
WPF:构建应用程序的更多相关文章
- iOS-马上着手开发iOS应用应用程序-第二部分构建应用程序
第二部分构建应用程序 1,应用程序开发过程 2,设计用户界面 3,定义交互 4,教程:串联图 1,应用程序开发过程 定义概念 设计用户界面 定义交互 实现行为整合数据 对象是应用程序的基石 类是对象的 ...
- 实战案例--Grunt构建Web程序
GruntJS构建Web程序.使用Gruntjs来搭建一个前端项目,然后使用grunt合并,压缩JS文件,熟练了node.js安装和grunt.js安装后,接下来来实战一个案例,案例是根据snandy ...
- Go基础系列:构建go程序
hello world 从一个简单的程序开始解释,将下面的内容放进test.go文件中,路径随意: package main import ( "fmt" ) func main( ...
- Maven构建应用程序常用配置(转)
来自:http://shiyanjun.cn/archives/180.html 使用Maven来构建应用程序,可以非常方便地管理应用相关的资源.众所周知,应用程序中涉及到的一些依赖关系,如Java应 ...
- 如何使Wpf浏览器应用程序被完全信任运行
原文地址链接:http://blogs.microsoft.co.il/maxim/2008/03/05/how-to-run-wpf-xbap-as-full-trust-application/ ...
- WPF浏览器应用程序与JS的互调用(不用WebBrowser)
首先说些题外话,很久没有写博客了,空间里面的大部分文章还是11年写的.那时候刚毕业就来到这家公司,参与到一个Asp.net MVC的项目开发中,这个项目是一个全新的项目,连项目开发框架都没有,亏得领导 ...
- WPF ClickOnce应用程序IIS部署发布攻略
WPF程序非常适合公司内网使用,唯一缺点就是客户端要安装.net框架4.0.优势也很明显,在客户端运行的是一个WinForm程序,自动下载,可以充分利用客户机的性能,而且是以当前的Windows用户权 ...
- 一步一步部署WPF浏览器应用程序
WPF浏览器应用程序与Silverlight,Asp.net相比,同是发布到服务器,在IE中运行.WPF浏览器应用程序部署起来却相对困难. 相信很多朋友在第一次部署WPF浏览器应用程序时,都遇到&qu ...
- WPF 构建无外观(Lookless)控件
原文:WPF 构建无外观(Lookless)控件 构建一个用户可以使用Template属性设置外观的WPF控件需要以下几步 1.继承自System.Windows.Controls.Control 2 ...
随机推荐
- golang Rsa
package models import ( "crypto/rand" "crypto/rsa" "crypto/x509" " ...
- Android 为应用添加数字角标
今天在论坛上看到了一个帖子,终于搞清了我很久以来的一个困惑,android到底能不能实现ios的角标效果,QQ是怎么实现的.看了这个帖子顿时终于解除了我的困惑. 先说一个下大概的思路: 大家都知道an ...
- SQL Server 获取服务器信息
最近做了一个小工具,里面涉及到一些取SQL Server 服务器信息的一些东西,找了好久,找到一个不错的,贴出来分享. 系统函数 SERVERPROPERTY ( propertyname ) 包含要 ...
- php的stdClass类
在PHP内核进行模块初始化操作时会自动加载这个函数, 这样,stdClass类的注册操作也就会被执行了.stdClass类是一个没有成员变量也没有成员方法的类. 它的所有的魔术方法,父类.接口等在初始 ...
- Backward Digit Sums(暴力)
Backward Digit Sums Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5664 Accepted: 32 ...
- poj 1118 Lining Up(水题)
再思考一下好的方法,水过,数据太弱! 本来不想传的! #include <iostream> using namespace std; #define MAX 702 /*284K 422 ...
- HDU 1134 卡特兰数 大数乘法除法
Problem Description This is a small but ancient game. You are supposed to write down the numbers 1, ...
- [C#]DataTable常用操作总结
].RowState == DataRowState.Unchanged) { //Your logic } //⑩Convert to ...
- C#获取单个字符的拼音声母
public class ConvertToPinYing { /// <summary> /// 汉字转拼音缩写 /// < ...
- Copy from chromium-dev!
https://app.yinxiang.com/pub/gguangle0/chromium-dev 做了一些搬运工的活..............