日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

一起谈.NET技术,WPF 基础到企业应用系列5——WPF千年轮回2

發布時間:2023/12/19 asp.net 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一起谈.NET技术,WPF 基础到企业应用系列5——WPF千年轮回2 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一,摘要

  首先很高興這個系列能得到大家的關注和支持,前端時間身體狀況不適,所以暫停了更新,對此表示非常抱歉,以后會逐漸加快進度,不過由于這是一個很長的系列,我也想把它寫好,所以以后也會慢慢來,在這個系列的過程中也會穿插發一些其他文章,比如Windows Azure、設計模式、WCF、Silverlight等,同時也會發一些自己的技術隨感和心得,反正只要自己寫得開心且對大家有幫助就行。由于自己才疏學淺且是對這些技術的使用總結和心得體會,錯誤之處在所難免,懷著技術交流的心態,在這里發表出來,所以希望大家能夠多多指點,這樣在使一部分人受益的同時也能糾正我的錯誤觀點,以便和各位共同提高。

  這篇課程主要是對上幾次課程的回顧和簡單深化,所以沒有講什么比較新的概念,不過掌握好了這篇,對后面的很多文章都有幫助,同時這一篇文章做Demo、構思、研究等也花費了不少時間,所以希望對大家有所幫助。

二,本文提綱

· 1.摘要

· 2.本文提綱

· 3.前篇回顧

· 4.Xaml基礎

· 5.脫離VS工具CSC編譯WPF

· 6.XamlReader與XamlWriter

· 7.本文總結

. 8.系列進度

三,前篇回顧

  在我們日常的開發中,軟件企業的開發人員一般會有兩種類型的工作:

    1,一類是用戶界面設計人員,他們關心的是軟件和用戶之間的交互,就是如何讓用戶體驗更好;

    2,另一類是軟件開發人員,他們關心的是軟件的架構設計、業務邏輯的處理和軟件功能的實現;

  在BS中,用戶界面設計人員使用HTML及其工具來設計界面,開發人員使用Java,C#,VB或其他語言來實現其中的邏輯,HTML網頁可以用到最終的產品中。

  在CS中,過去我們一直沒有分開這兩種不同性質的工作。用戶界面設計人員通常和開發人員使用不同的工具,當界面設計人員設計好用戶界面時,他們的工作并沒有用到最終的產品中,而只是用來展現某種概念或工作流程。

  XAML實現了互聯網應用程序和桌面應用程序的統一,界面設計人員可以使用XAML或基于XAML的工具(如微軟的Design和 Blend) 來設計CS或BS應用程序的界面。程序開發人員則可以在此基礎上使用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:Class="XamlReaderWriterDemo.Window2"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
Title
="Window2" Height="300" Width="300">
<Grid>
<Button Height="23" Name="btnTest" Margin="98,72,105,0" VerticalAlignment="Top">Button</Button>
</Grid>
</Window>

  這里我們需要特別注意的是 XamlReader 載入的 XAML 代碼不能包含任何類型(x:Class)以及事件代碼(x:Code),也就是說要XAML自身的代碼才受支持(這個也在WPF揭秘這本書講到過)。那么我們可以用 XamlWriter 將一個編譯的 BAML 還原成 XAML了,具體代碼如下:

//XamlWriter
var xaml = XamlWriter.Save(new Window2());
MessageBox.Show(xaml);

  輸出的Message如下(為了效果更好看一些,我粘貼到了VS):

<Window2 Title="Window2" Width="300" Height="300" xmlns="clr-namespace:XamlReaderWriterDemo;assembly=XamlReaderWriterDemo" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<av:Grid>
<av:Button Name="btnTest" Height="23" Margin="98,72,105,0" VerticalAlignment="Top">Button</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新功能

總結

以上是生活随笔為你收集整理的一起谈.NET技术,WPF 基础到企业应用系列5——WPF千年轮回2的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。