2011年9月19日 星期一

WPF第一章

1.一個應用當中只能有一個Application物件,這個物件是看不見的,不像Window物件,看得到視窗,有標題列。

2.建立Window物件跟Application物件的順序沒有一定,只有一些原則要遵守,Application的Run必須保留在最後,因為Run方法一旦被呼叫就不會返回,直到視窗被關閉結束。

3.可以不要呼叫Window的Show方法而是直接把Window物件當作參數傳遞給Run方法,這樣Run方法會去呼叫Window物件的Show方法的。

4.Application類別具有一個Static Property名為Current,裡頭包含一個MainWindow物件,這個取用方式有個注意事項,宣告產生Application物件必須在宣告產生Windows物件之前完成,或是呼叫Run的時候傳入的Window物件,否則會得到Null reference exception。Current裡頭也包含著Windows的Collection類別,可以透過他取得所有的

5.Application類別具有數個有用的事件,大多數的事件都有對應的Protected方法可以發出事件,例如Startup事件是利用OnStartup方法所產生。當呼叫Application的Run()之後,就會立刻呼叫OnStartup方法,當Run返回時,則會立刻呼叫OnExit(),可以用這些事件的時機來作應用程式的初始化跟清除。

6.一個程式可以有多個視窗

2011年9月13日 星期二

什麼是WPF

開始年份
語言
介面
1985年
C
Windows API
1992年
C++
MFC程式庫
2001年
C#或C++
Windows Form
2006年
C#或C++
Windows Presentation Foundation


從最開始的Windows程式只能利用C語言以及Windows API,到過去幾年,開始出現最多人使用的的MFC程式庫,之後演進到受管控的(Managed Code)現代化的NET的Windows Form設計方式,這幾年則出現WPF這個新一代的設計方案。

WPF在繪圖、動態效果卓越提升,除了2D,還支援3D的效果。除了用程式語言C#開發,也能用XMAL語法來開發,新一代的Silver Light就是延續著WPF而精簡出來的新一代網頁開發工具。

2011年9月9日 星期五

C#如何引用dll

如果是很單純的要呼叫C#的dll
只要[專案][加入][參考 ],把dll加入之後




[DllImport("yyyyyy.dll")]
public extern static void gggggg();
yyyyyy表示該dll的檔名
gggggg表示要呼叫的函式名稱


最後,在你想呼叫該函式的地方:
xxxxxx.classname.gggggg();即可,其中classname是該function所在的class名稱,因為函式一定要存在於Class當中,且注意,該函式一定要宣告為static才行

ListBox 相關元件對Item或Select的CopyTo差異在哪裡?

List.Item.CopyTo( Object, Index )
此方法不支援 Int 陣列,僅支援 String 與 Object
因為該集合是項目內容,可能為非數字




List.SelectedIndices.CopyTo( Array, Index )
此方法支援 Int 等型態的陣列
因為該集合是項目 Index,一定是數字

2011年9月8日 星期四

C# Background Worker介紹

Background worker:一個簡單、好用的Thread方案
它可以以很簡單的方法產生工作執行緒,並且保持主執行緒的可用性,並且也支援回報狀態與交換資料能力,更方便的是他在處理跨執行緒使用UI介面的部分,大多時候可以不用透過Delegate、Invoke、WaitCallBack......等等複雜的觀念與機制,因為他已經幫你實作掉了。




寫法:可以由工具箱當中直接拉Background worker的控制項到Form上面,這樣也可以直接雙擊IDE介面來產生事件Method。


或是也可以自己宣告來產生實體,自己設定Event物件與Event Method。








Method:
RunWorkerAsync(object)
呼叫此函式,會讓Background worker以多執行緒的方式來執行DoWork()內的程式




DoWork(object sender, DoWorkEventArgs e)
將你想執行的耗時的程式片段寫在其中,在呼叫Background worker的RunWorkeAsync()時,就會以多執行緒的方式執行此函式。注意,在這個函式中,不可以執行任何跟UI有關的動作,不允許跨執行緒存取UI。




RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
當DoWork()被執行完成之後,會自動呼叫這個函式,如果預期完成之後要做什麼動作,可以寫在這個函式裡。這個函式可以存取Main Thread的UI,不會有誇執行緒的問題。或者說,除非寫法上有多執行緒的特殊用法,否則一般來說這個函式會在Main Thread執行,也因此才不會有跨執行緒存取UI的問題產生。





ProgressChanged(object sender, ProgressChangedEventArgs e)
Background worker提供了一個ReportProgress()的函式,可以隨時對這個背景執行的工作定義完成進度,而通常,想當然爾,這個函式,會在DoWrok裡呼叫,依照做的進度,來呼叫函式傳給Background worker,而當你呼叫了ReportProgress()之後,就會立刻一併觸發ProgressChanged()。而這個函式可以存取Main Thread的UI,不會有誇執行緒的問題。或者說,除非寫法上有多執行緒的特殊用法,否則一般來說這個函式會在Main Thread執行,也因此才不會有跨執行緒存取UI的問題產生。 也就是說,一般我們會把需要變更UI的程式寫在這裡,而不會寫在DoWork(),當DoWrok()當中的,需要對UI有什麼控制時,就以回報進度的方式,在ProgressChanged()裡頭來做。

ListView 的使用教學

  • ListView的屬性View有五種設定值,分別是LargeIcon、Details、SmallIcon、List、Tile,代表著五種不同的資料檢視模式


  • Item屬性可以編輯項目,這些項目,就是會呈現在ListView上的所有項目,當你以Details以外的模式查看資料就可以看到這些項目了。但是,此時在檢視模式「Details」看則是空白。


  • 如何在Detail模式下可以看到資料呢?你必須編輯Columns屬性,只要新增一個Column,就能顯示出這些項目了。


  • 如果再新增Columns,會發現,不會顯示多的資料出來,後面幾欄都會是空的,必須編輯Items的SubItems屬性,這個項目會對於剛剛的Items屬性增加細節資訊,這些細節資訊,會對應到兩種顯示模式,分別是Details跟Tile,對於Details,則是看Columns的數量,如果Columns的數量夠多才能將細節資訊顯示出來,而對於Tile,增加的資訊,會列在主資訊旁邊,有點像是註解般的,但是要注意的是,Columns屬性還會影響檢視模式「Tile」的顯示,Columns有幾個,這邊才會把每個Items的第幾個SubItems顯示出來的。

  • 而群組屬性則是可以將所有的Items分成幾個不同的群組來顯示資料,編輯Groups屬性時會發現你無論新增幾個Groups,對畫面的影響僅有畫面多了一個Default的標題,所有項目都被放在Default標題之下。接下來要做的動作是到Items的屬性設定畫面,將Group屬性選擇成剛剛建立的Group,凡是沒有指定的都會放在Default那個區塊底下的。

  • 還可以放入ImageList元件,將圖片設定好,就可以在ListView的LargeImageList與SmallImageList屬性設定到ImageList元件,這樣在檢視模式:「LargeIcon」就可以看到大圖示,而其他的模式則可以看到指定小圖。

字串格式與對齊解說(三)數值篇

String.Format( String, Object )的使用方式有點類似之前C的printf()
舉例來看:

ResultStr = String.Format( "謝謝您在{1:##}分鐘內閱讀本文章第 {0:00###} 次了.",123,60);
或
ReadAmount = 123;
ResultStr = String.Format( "謝謝您在{1:##}分鐘內閱讀本文章第 {0:00###} 次了.",ReadAmount,60 );
這樣的語法,就能得到 ResultStr = "謝謝您在60分鐘內閱讀本文章第00123次了。也就是說,可以傳入由字串與格式項目與參數的組合來達到串出所需字串的目的,而在 { } 兩個大括弧中間的,就是控制格式化的部分,而大刮號之間的第一個數字,是表示要用後面所給的第幾個參數,通常會是需要被格式化的「數字、時間、.....等等格式」,比方,以第二個例子來說,就會拿後面的參數60代到前面的{1}那邊,而參數ReadAmount則是會被代到前面的{0}的地方而 : 符號後面的部分,則是可以用很複雜的控制代碼,控制代碼,分成很多種。

我們先看常用的標準的格式代碼(格式碼通常不用在意大小寫,都適用)
----------------------------------------------------------------------------------------------
C 表示貨幣,並且可接著一個數字,來表示要的精度到小數第幾位,不接數字則會使用目前NumberFormatInfo物件所提供的預設貨幣精確度。 
例如:String.Format( "{0:C5}", 12345.678901234 )則會得到NT$12,345.67890  
 
D 表示十進位(只支援整數型別),並且可接著一個數字,來表示要顯示多少位數,不夠的部分會於左邊補零
例如:String.Format( "{0:D8}", 12345 )則會得到00012345 
 
E 表示科學符號,並且可接著一個數字,來表示要的精度到小數第幾位,不接數字則預設六位小數
例如:String.Format( "{0:E}", 12345.678901234 )則會得到1.234568E+004
 

F 表示浮點數,並且可接著一個數字,來表示要的精度到小數第幾位,不接數字則會使用目前 NumberFormatInfo 物件的 NumberDecimalDigits 屬性所提供的預設數值精確度。
例如:String.Format( "{0:F3}", 12345.678901234 )則會得到12345.679
 

G 表示一般,並且可接著一個數字,來並且可接著一個數字,來表示要顯示多少位數(包含整數與小數的部分),而可能轉為科學記號,也可能轉出浮點數,(說明文件說會挑以最精簡顯示方式來顯示,但很難懂),直接看範例
例如:String.Format( "{0:G3}", 12345.678901234 )則會得到123e+04
例如:String.Format( "{0:G4}", 12345.678901234 )則會得到1235e+04
例如:String.Format( "{0:G5}", 12345.678901234 )則會得到12346
例如:String.Format( "{0:G6}", 12345.678901234 )則會得到12345.7


N 表示數字,並且可接著一個數字,表示要的精度到小數第幾位,不接數字則會使用目前 NumberFormatInfo 物件的 NumberDecimalDigits 屬性所提供的預設數值精確度。
例如:String.Format( "{0:N3}", 12345.678901234 )則會得到12345.679
 

P 表示百分比,並且可接著一個數字,來表示要的精度到小數第幾位,不接數字則預設六位小數
例如:String.Format( "{0:E}", 12345.678901234 )則會得到1.234568E+004
 

X 表示16進位,並且可接著一個數字,來表示要顯示多少位數,不夠的部分會於左邊補零。這個X的大小寫,有意義,會指定輸出的16進位的英文部分要大寫還是小寫。
例如:String.Format( "{0:X8}", 123456 )則會得到0001E240



我們再看常用的自訂的格式代碼
----------------------------------------------------------------------------------------------
0 的用法是會讓轉出來的字串被數字取代,但是如果沒數字的地方,會補零。
# 的用法是會讓轉出來的字串被數字取代,但是如果沒數字的地方,不會有數字。
. 的用法是決定轉出的字串的小數點對齊位置。
\ 的用法是讓這些保留控制碼也可以被顯示出來。
其他符號都會直接被顯示在轉出的字串裡。


例如:
String.Format( "{0:000000}", 1234 )則會得到001234
String.Format( "{0:000.000}", 1234.56 )則會得到1234.560
String.Format( "{0:######}", 1234.56 )則會得到1234
String.Format( "{0:###.###}", 1234.56 )則會得到1234.56
String.Format( "{0:###.000}", 1234.56 )則會得到1234.560




補充PadLft與PadRight