在 windows 下使用 vs2010 開發,未深入研究。
c# 與 .net 開發,一堆又一堆的新名詞,頭暈目眩,比如 CLR / apartments / STA / MTA / COM
吐槽無力,只一個問題:微軟真的是軟件公司,而不是文學公司?
1. 工程代碼結構
創建 Windows Forms Application 工程后,自動生成如下代碼:
Form1.cs 與 Form1.Designer.cs 是 2 個文件,一起定義了一個 form 的行為/樣式等。在 vs2010 中會折疊在一起。
其中,Designer 中定義樣式。事件監聽、事件處理都在 form.cs 中定義。
雙擊 form.cs 會打開 UI 效果界面,可以直接拖拽完成界面布局。右鍵 view code 可以查看 form1.cs 源碼。
Program.cs 內定義了 main 函數,是啟動文件。
用一個 App run 一個 form。
[STAThread]/[MTAThead] 指定單/多線程運行模式。
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace AppDemo { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } }
2. Form.cs 與 Form.Designer.cs
form1.cs 與 designer.cs 2個文件定義的是同一個 namespace 下的 同一個 class
每一個文件定義時,都使用了 partial class
界面布局的代碼,一般自動生成,在 Designer 中。
手寫的代碼主要是事件處理,一般放在 form.cs 中
form.cs 的構造函數中,一般會先調用 Designer.cs 中定義的 InitializeComponent() 完成界面初始化。
在 InitializeComponent 中會聲明每個控件的索引 private System.Windows.Forms.Button button1;
在 form.cs 中可以直接用過變量名 button1 操作該控件。
所以,form.cs 的構造函數中,一般先調用 InitializeComponent。
Designer.cs 中,InitializeComponent 初始化界面。Dispose 方法釋放資源。釋放時需要注意不要造成資源泄露。
// --------------- Form1.cs ----------------------------------- using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace AppDemo { public partial class Form1 : Form { public Form1() { InitializeComponent(); } } } // ------------------- Form1.Designer.cs ------------------------- namespace AppDemo { partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code } }
3. 資源文件 與 resx
exe 或者 dll 文件需要依賴其它文件得以正常運行,
最簡單的做法是:把依賴文件拷貝到客戶端,程序內部用相對路徑讀取。
這一般是可以的,但若客戶刪除了這些資源,則會導致不可預期的效果。
通過資源文件,可以把這些文件嵌入到 exe 或者 dll 中。
資源文件可分為 2 類:.resx 和 .resources。前者是 xml 格式,后者是二進制。
只有當前 solution 存在同名的 .cs 文件時,.resx 文件才能正常工作。resources 則無此限制。
通過 System.Resources 下的 ResourceWriter 可以生成資源文件,Generate 產生文件,Close 關閉文件。
創建實例后,即可通過 AddResource 方法添加資源。第一個參數是標示符,可以在代碼中通過標示符使用資源。
資源文件中一般存三種類型的數據:byte流(byte[])、對象(object)和字符串(string)。
ResourceWriter rw = new ResourceWriter ( "filename.resources" ) ; rw.Generate ( ) ; // 產生文件 rw.Close ( ) ; // 添加資源 public void AddResource ( str_identifier , byte [ ] ) ; public void AddResource ( str_identifier , object ); public void AddResource ( str_identifier , str_value ) ;
resources.ApplyResources( this.myButton, str_identifier ); // 為 this.myButton 使用資源 str_identifier
this.ApplyResource();
4. 多國語言與本地化
4.1 添加多國語言支持
在界面上添加組件后,會生成 .resx 文件,vs2010 中折疊在對應的 form.cs 下。
這是默認語言的資源文件,文件名為 form1.resx
若要開發其他語言版本,在對應 form 右側的屬性菜單中,將 Localizable 設為 True,並將 language 設為所需語言即可。
設置新的顯示文本后保存,會生成對應語言的 .resx 文件。文件名格式為 form1.language-Location.resx,例如:簡體中文為 form1.zh-CN.resx
- 僅當 Language 為 default 時才可以添加或刪除界面中的組件。
- 僅當設定為新 language,且修改過顯示內容后,才會創建對應的資源文件。
- 僅當選定 form 時,才能在右側屬性菜單中設置語言。若選中 form 中的 button、text 等組件時,無法設置本地化屬性。
- 添加多國語言支持后,默認語言的 form1.resx 中不再包含顯示文字 Text、控件大小 Size、顯示位置 Location 等,而是放在了對應語言的資源文件中,通過 ApplyResources 取用。
4.2 獲取與設定運行時語言
兩個關鍵概念:
- CurrentCulture:默認值是操作系統的用戶區域設置,它在“區域選項”控制面板中設置。
- CurrentUICulture: 默認值是操作系統的用戶界面 (UI) 語言,即操作系統用戶界面所使用的語言。
System.Globalization.CultureInfo.InstalledUICulture.Name; // 獲取當前運行語言 System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo( "zh-CHS" ); // 設置當前運行語言
5. 頁面布局與樣式設定
SuspendLayout() 調用后控件的布局邏輯被掛起,直到調用 ResumeLayout() 方法為止。
當調整控件的多個屬性時,將先調用 SuspendLayout 方法,然后設置控件的 Size、Location、Anchor 或 Dock 屬性,
最后調用 ResumeLayout 方法以使更改生效。