北京网站建设加q.479185700,今年的公需课在哪个网站做,自建网站 服务器,南充网站开发一#xff0c;摘要 首先很高兴这个系列能得到大家的关注和支持#xff0c;前端时间身体状况不适#xff0c;所以暂停了更新#xff0c;对此表示非常抱歉#xff0c;以后会逐渐加快进度#xff0c;不过由于这是一个很长的系列#xff0c;我也想把它写好#xff0c;所以以…一摘要 首先很高兴这个系列能得到大家的关注和支持前端时间身体状况不适所以暂停了更新对此表示非常抱歉以后会逐渐加快进度不过由于这是一个很长的系列我也想把它写好所以以后也会慢慢来在这个系列的过程中也会穿插发一些其他文章比如Windows Azure、设计模式、WCF、Silverlight等同时也会发一些自己的技术随感和心得反正只要自己写得开心且对大家有帮助就行。由于自己才疏学浅且是对这些技术的使用总结和心得体会错误之处在所难免怀着技术交流的心态在这里发表出来所以希望大家能够多多指点这样在使一部分人受益的同时也能纠正我的错误观点以便和各位共同提高。 这篇课程主要是对上几次课程的回顾和简单深化所以没有讲什么比较新的概念不过掌握好了这篇对后面的很多文章都有帮助同时这一篇文章做Demo、构思、研究等也花费了不少时间所以希望对大家有所帮助。 二本文提纲 · 1.摘要 · 2.本文提纲 · 3.前篇回顾 · 4.Xaml基础 · .脱离VS工具CSC编译WPF · .XamlReader与XamlWriter · .本文总结 . .系列进度 三前篇回顾 在我们日常的开发中软件企业的开发人员一般会有两种类型的工作 1,一类是用户界面设计人员他们关心的是软件和用户之间的交互就是如何让用户体验更好 2,另一类是软件开发人员他们关心的是软件的架构设计、业务逻辑的处理和软件功能的实现 在BS中用户界面设计人员使用HTML及其工具来设计界面开发人员使用JavaC#VB或其他语言来实现其中的逻辑HTML网页可以用到最终的产品中。 在CS中过去我们一直没有分开这两种不同性质的工作。用户界面设计人员通常和开发人员使用不同的工具当界面设计人员设计好用户界面时他们的工作并没有用到最终的产品中而只是用来展现某种概念或工作流程。 XAML实现了互联网应用程序和桌面应用程序的统一界面设计人员可以使用XAML或基于XAML的工具如微软的Design和 Blend) 来设计或应用程序的界面。程序开发人员则可以在此基础上使用C#或VB.NET等来开发相应的功能这样界面设计人员的工作便自然过渡到最终产品中。 在XAML中用户界面用XML的元素或属性来表示。WPF引擎把XAML描述的UI元素解释为相应的.NET对象从而在桌面程序或Silverlight网页上创建相应的控件。如下图所示 上面这副就是传统的WinForm开发模式这两种人没有分离开来所以在很多企业里就形成了开发人员既要做UI也要做程序的境地。 上图就是现在的WPF和Silverlight程序的开发模式这两类人可以分开来工作他们都可以对Window1.xaml进行修改和加载所以这样就使分工更专业了由于大家专注于某一个方面分工协作的同时质量和效率也逐渐提高了。 前几篇介绍了一些基础知识那么这篇也简单的回顾一下下面第一幅图是WPF的执行顺序第二副图是WPF的一个项目的构成第三幅图是WPF所对应的IL代码这些图处理得不好还望各位见谅。 WPF的执行顺序 WPF的一个项目的构成 WPF所对应的IL代码 四Xaml基础 这个部分要讲的东西就太多了由于这篇文章篇幅有限同时我觉得用代码诠释能让大家可以更清晰地理解所以就讲得随意一些通过一个Demo介绍WPF对资源、类、控件的调用和处理对Dictionary资源、Application资源、window资源以及控件资源的应用等如下图所示本篇所有代码在评论的第一条 由于这些概念比较简单所以我就不花费大的篇幅来讲这些它们感兴趣或者对这些知识还有不清楚的朋友可以下载这个Demo进行查看或调试我觉得对初学者很有帮助。 五脱离VS工具CSC编译WPF 为了更好的认识WPF的编译和执行过程我们可以暂时弃用我们熟悉的VS工具选用记事本写如下的代码: using System;using System.Windows;namespace KnightsWarrior.HelloWorld{class HelloWorld { [STAThread]public static void Main() { Window win new Window(); win.Height 300; win.Width 400; win.Title Hello,KnightsWarrior!; win.Show(); Application app new Application(); app.Run(); } }} 然后保存到D:\HelloWorld.cs 这个位置通过CMD或者VS cmomand Line中输入以下编译命令 csc.exe /out:D:\HelloWorld.exe D:\HelloWorld.cs /reference:C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\presentationframework.dll /reference:C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\windowsbase.dll /reference:C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\presentationcore.dll 然后就可以手动编译成功了。 那么通过 可以查看到它的IL代码如果感兴趣的朋友也可以进行详细的分析。 如果对MSIL比较熟悉的朋友也可以用记事本写同样功能的IL代码由于没有对WPF窗体的IL做具体研究所以用Console程序代替,等过一段时间再研究WPF控件的IL代码. .assembly extern mscorlib { auto }.assembly HelloApp {}.module HelloApp.exe.namespace HelloApp{ .class public Program extends [mscorlib]System.Object { .method static private void Main(string[] args) { .entrypoint ldstr Hello, KnightsWarrior! call void [mscorlib]System.Console::WriteLine(string) ret } }} 然后打开 Visual Studio Command Prompt使用 ILASM 开始编译。 这样你就更能看清楚编译器背后的秘密同时也能跟踪每一步执行的操作同时对一些简单的内存泄露问题也比较容易察觉到。当然现在也有很多工具可以跟踪这些问题我这里只是写一种思路大家可以根据自己的爱好取舍。 六XamlReader与XamlWriter System.Windows.Markup 命名空间中提供了 XamlReader、XamlWriter 两个类型允许我们手工操控 XAML和BAML 文件。 XamlReader类除了定义Load的实时加载之外也定义了异步方法可以异步解析XAML中的内容。我们可以在XamlReader对象的实例里调用它们。如果在读取一个大文件时要保持用户UI的响应性就可以使用异步读取的方法。和异步读取方法匹配的还有一个CancelAsync方法用于停止读取操作。XamlReader 还定义了LoadCompleted事件在读取完成后会触发该事件,那么我们就可以把读完后要做的事情都在这里进行处理。 XamlWriter 供一个静态 Save 方法多次重载该方法可用于以受限的 XAML 序列化方式将所提供的运行时对象序列化为 XAML 标记。这句话似乎有点难懂其实简单的说就是把它序列化为我们需要的类型。 具体功能代码如下 通过XamlReader 动态构建并实例化一个Window。 //XamlReader StringBuilder strXMAL new StringBuilder(Window );strXMAL.Append(xmlns\http://schemas.microsoft.com/winfx/2006/xaml/presentation\ );strXMAL.Append(xmlns:x\http://schemas.microsoft.com/winfx/2006/xaml\ );strXMAL.Append(Title\Window2\ Height\600\ Width\600\);strXMAL.Append(/Window);var window (Window)XamlReader.Parse(strXMAL.ToString());window.ShowDialog(); 同时我们还可以从文件流中读取并操作。 //XamlReader using (var stream new FileStream(Window2.xaml, FileMode.Open)){ var window2 (Window)XamlReader.Load(stream); var button (Button)window2.FindName(btnTest); button.Click (x, y) MessageBox.Show(Knights Warrior); window2.ShowDialog();} Window2.xaml 的代码 Window x:ClassXamlReaderWriterDemo.Window2 xmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:xhttp://schemas.microsoft.com/winfx/2006/xaml TitleWindow2 Height300 Width300GridButton Height23 NamebtnTest Margin98,72,105,0 VerticalAlignmentTopButton/Button/Grid/Window 这里我们需要特别注意的是 XamlReader 载入的 XAML 代码不能包含任何类型(x:Class)以及事件代码(x:Code)也就是说要XAML自身的代码才受支持这个也在WPF揭秘这本书讲到过。那么我们可以用 XamlWriter 将一个编译的 BAML 还原成 XAML了具体代码如下 //XamlWritervar xaml XamlWriter.Save(new Window2());MessageBox.Show(xaml); 输出的Message如下为了效果更好看一些我粘贴到了VS: Window2 TitleWindow2 Width300 Height300 xmlnsclr-namespace:XamlReaderWriterDemo;assemblyXamlReaderWriterDemo xmlns:avhttp://schemas.microsoft.com/winfx/2006/xaml/presentationav:Gridav:Button NamebtnTest Height23 Margin98,72,105,0 VerticalAlignmentTopButton/av:Button/av:Grid/Window2 XAML 的动态载入在使用动态换肤以及运行时加载等场景颇为有用以后也会慢慢接触。 由于使用XamlReader和XamlWriter有很多限制比如我想把一批Baml转化为Xaml再比如我想指定Baml的路径然后通过Load的方式载入那么这些场景就无法通过XamlReader和XamlWriter完成了这个让我也做过不少的Demo也跟踪了很长时间的IL代码在百思不得其解之后和周永恒、Virus等讨论了一下最后终于找到了一个方案如下代码所示 public static class BamlWriter {public static void Save(object obj, Stream stream) {string path Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory(path);try {string xamlFile Path.Combine(path, input.xaml);string projFile Path.Combine(path, project.proj);using (FileStream fs File.Create(xamlFile)) { XamlWriter.Save(obj, fs); } Engine engine new Engine(); engine.BinPath RuntimeEnvironment.GetRuntimeDirectory(); Project project engine.CreateNewProject(); BuildPropertyGroup pgroup project.AddNewPropertyGroup(false); pgroup.AddNewProperty(AssemblyName, temp); pgroup.AddNewProperty(OutputType, Library); pgroup.AddNewProperty(IntermediateOutputPath, .); pgroup.AddNewProperty(MarkupCompilePass1DependsOn, ResolveReferences); BuildItemGroup igroup project.AddNewItemGroup(); igroup.AddNewItem(Page, input.xaml); igroup.AddNewItem(Reference, WindowsBase); igroup.AddNewItem(Reference, PresentationCore); igroup.AddNewItem(Reference, PresentationFramework); project.AddNewImport($(MSBuildBinPath)\Microsoft.CSharp.targets, null); project.AddNewImport($(MSBuildBinPath)\Microsoft.WinFX.targets, null); project.FullFileName projFile;if (engine.BuildProject(project, MarkupCompilePass1)) {byte[] buffer new byte[1024];using (FileStream fs File.OpenRead(Path.Combine(path, input.baml))) {int read 0;while (0 (read fs.Read(buffer, 0, buffer.Length))) { stream.Write(buffer, 0, read); } } }else {throw new System.Exception(Baml compilation failed.); } }finally { Directory.Delete(path, true); } } }public static class BamlReader {public static object Load(Stream stream) { ParserContext pc new ParserContext();return typeof(XamlReader) .GetMethod(LoadBaml, BindingFlags.NonPublic | BindingFlags.Static) .Invoke(null, new object[] { stream, pc, null, false }); } } 上面的代码大家可以试一下运行效果。或者有更好的方式也请告知。 七本文总结 本篇主要对前几次的课程进了一些简单的回顾同时用一个比较全的Demo介绍了Xaml中引用各种控件和类等另外对脱离VS工具CSC编译WPF以及XamlReader与XamlWriter 做了比较详细的介绍。下篇我们将进入WPF布局的世界进行漫游争取和布局控件及应用来一个全接触 最后圣殿骑士 会尽心尽力写好这个系列同时由于是自己对这些技术的使用总结和心得体会错误之处在所难免怀着技术交流的心态在博客园和51CTO发表出来所以希望大家能够多多指点这样在使一部分人受益的同时也能纠正我的错误观点以便和各位共同提高后续文章敬请关注 八系列进度红色标示已发布 · 1. WPF 基础到企业应用系列1——开篇有益 · 2. WPF 基础到企业应用系列2——WPF前世今生 · 3. WPF 基础到企业应用系列3——WPF开发漫谈 · 4. WPF 基础到企业应用系列4——WPF千年轮回 · 5. WPF 基础到企业应用系列5——WPF千年轮回 续前缘 · 6. 使用面板做布局几种布局控件的XAML及CS代码综合布局等 · 7. 依赖属性、附加属性基本、继承、元数据 · 8. 路由事件、附加事件 · 9. 命令 · 9. WPF控件分类介绍与使用技巧ContentControl、HeaderedContentControl…… Decorator · 10. 尺寸缩放、定位与变换元素 · 11. 资源 · 12. 数据绑定基本、值转换、验证、集合的筛选、排序、分组、主从、数据提供者 · 13. 样式 · 14. 模板 · 15. 多语言、皮肤和主题 · 16. 2D图形 · 17. 3D图形 · 18. 动画几种动画的应用 · 19. 音频、视频、语音 · 20. 文档、打印、报表 · 21. 用户控件和自定义控件 · 22. Win32、Windows Form以及ActiveX之间的互用性 · 23. 构建并部署应用程序ClickOnce部署、微软setup /InstallShield自动更新组件 · 24. WPF的模式讲解及实例MVC Demo · 25. WPF的模式讲解及实例MVP Demo · 26. WPF的模式讲解及实例MVVM Demo · 27. 性能优化WPF项目的瓶颈 · 28.一个完整WPF项目普通架构版 · 39. 一个完整WPF项目MVVM架构版 · 30. WPF 4.0新功能