從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

第八節的內容早已寫好釋出,結果一直在稽核中,不知道觸動了哪條神經。

評論中看到有一些網友都在問為什麼不用WPF來開發,在這裡我統一說明下:

1)WPF介面設計相對複雜。

由於它是向量的,需要額外有很多容器做對齊方面的調整,並且很多調整是要直接寫xaml才能獲得良好的效果。Winform是所見即所得,簡單拖放就能看到效果、滿足功能。我第一階段的教學目的主要是想讓同學們系統地瞭解一個軟體產品開發的整個過程,從基礎做起,為後續開發打基礎,不想花太多的精力放在介面設計上。等到同學們有了程式設計的基礎,再在已有的資料和業務的基礎上做介面的改良,也會容易很多。

2)WPF應用場景較Winform並無明顯優勢。

即便是用WPF來設計,目前也只能Windows系統下執行,無法實現跨平臺。這與普通的Winform差別就僅限於介面表現,沒有本質上的差別。Winform透過錨定也可以一定程度地實現縮放。單就開發私人日記這個專案來說,總體差別不大,但是Winform的開發效率卻很高。當然如果你的專案需要大量的圖表展現,那麼應該優先考慮用WPF開發,如果只是一般的工具軟體,Winform足夠了,WPF個人感覺沒必要。

總結來說,第一階段綜合考慮教學和開發效率,採用Winform來開發價效比最高。另外,我想給大家透露下,對軟體產品而言:功能是雪中送炭,介面只是錦上添花。大家不要小看Winform應用,我現在軟體產品的大部分收入都是來自Winform開發的程式。現在PC端還是Windows的天下,使用者看中的是你的軟體能不能解決他的問題,出現問題你能不能快速解決,介面再花哨功能和維護跟不上也是白搭。

當然如果大家的呼聲很高,可以在後續再增加一個WPF的專案來教學。好了,接下來我們開始今天的內容。

在開始任務前,又發現了一個小Bug:分類管理中,右鍵選單新建功能,一旦關閉對話方塊,樹控制元件會自動將第一個節點設定為選中狀態,導致無法建立根目錄的情況再次發生。查看了一下樹控制元件的屬性,並沒有禁止自動選中節點的屬性可以設定。那我們還是改下程式碼吧:

從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

之前的程式碼是在彈出分類管理對話方塊之後再判斷是否有選中節點,現在在彈出對話方塊之前把狀態暫存,這樣就不會因為關閉後自動選中節點而無法建立根目錄了。再次執行檢視,問題得到解決。

上一節我們實現了分類管理介面的操作聯動,這節開始實現資料聯動。

上一節彈出的分類管理介面是這樣的:

從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

幾個輸入框需要使用者手動輸入資料是沒問題的,所屬分類與型別,這個是下拉框,既然是下拉框肯定要事先有資料可供使用者選擇的,那麼如何來向下拉框中錄入資料呢?本節開始介紹:

一、初始化窗體

要想在介面顯示前向下拉框控制元件中新增資料,需要先找到初始化窗體的事件,對應Form中的Load事件。

從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

雙擊自動建立事件程式碼,CategoryManagerForm_Load就是CategoryManagerForm的介面初始化函式,我們對控制元件的初始化操作都在這個函式中完成。

二、初始化分類型別

我們需要實現兩個ComboBox的初始化,一個是所屬分類cbxParent,一個是分類型別cbxType。

分類型別cbxType相對簡單,我們先來實現它,程式碼如下:

從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

看到上述程式碼,我估計又會有同學懵了。這是一堆什麼玩意,以前從來沒見過啊。對初學者來說這種程式碼實在不能算友好,不過只要明白程式碼含義了,理解起來也不那麼困難。

先看第一段

List> listType = new List>()

這裡面我使用了兩種模板類,一個是List,一個是Tuple。

先來說List,英文直譯是列表,注意跟資料結構學的連結串列並不是一個概念。它是一個封裝好的類,專門用來存取順序資料。要比連結串列功能強大得多。並且它是一個模板類。

什麼是模板類呢?我們之前有講到過類,類是用來抽象現實資料的,而模板類則是用來創造類的,靈活運用可以大大減少程式碼量。比如我現在需要兩個列表:一個專門儲存int型資料列表,一個專門儲存string型資料列表。如果沒有模板類,我需要建立兩個類,然後對他們進行分別宣告和實現變數、方法等,可能90%的程式碼都是重複的。現在有了List模板類,我只需要在程式碼中宣告List就創造了int型列表的類;宣告List就創造了string型列表的類,非常簡單。把模板類類化就是在<>中指定要類化的資料型別。

所以上面的程式碼就是聲明瞭一個Tuple型別的列表,取名為listType。

明白了模板類,再來看下看下這個Tuple是什麼東西?

Tuple英文直譯是元組的意思,較難理解,不過它後面也帶<>的,所以這也是一個模板類。可以理解為:可以定義成各種資料型別組合的一個模板類。比如以分類資料Model。Category為例,我們完全可以把它用Tuple來定義:Tuple,有同學就表示疑問了:既然有這個Tuple了,那還要自己定義幹嘛,都用Tuple來定義不就好了嗎?

這個要看應用場景:

1)Tuple只能定義資料,沒辦法像類一個樣定義方法;

2)Tuple裡面的資料名稱都是Item1、Item2這種型別的,不易閱讀;

3)Tuple能存放的資料型別最多是8個;

所以,簡單臨時用下的類,我們可以使用Tuple來快速宣告,其他位置還需要複用的或是需要有方法的類,還是需要用顯式的來宣告。

上面程式碼中Tuple就是宣告一個具有兩個string型別的類,一個值用來儲存分類型別的編碼,一個值用來儲存分類型別的名稱。

下面程式碼就是對listType 進行初始化,目前為了讓程式能跑起來看到效果。

{

new Tuple(“正常”, “Normal”),

new Tuple(“程式碼”, “Code”),

};

以上對Tuple的使用,主要目的是為了教學和演示方便,後續如果功能上有需要,可能還會變更程式碼。

程式執行到這一步結束,分類型別的資料就有了,再繼續看程式碼:

cbxType。DataSource = listType;

cbxType。DisplayMember = “Item1”;

cbxType。ValueMember = “Item2”;

cbxType。SelectedValue = “Normal”;

這4句就是用來繫結資料的:

cbxType。就是指分類型別控制元件,這種以後就不解釋了。

DataSource是資料來源的意思,用來指定comboBox的資料來源,那肯定就是上面的listType了;

DisplayMember是下拉框每項顯示文字用資料來源中的資料型別的哪個屬性,listType的資料型別是Tuple,那就是Item1了;

ValueMember 是下拉框每項的值用資料來源中的資料型別的哪個屬性來表示,那就是Item2了;

SelectedValue 是用哪條資料來作為預設的值;

程式碼理解之後,我們來跑下程式。

從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

下拉框出現了我們預期的文字,但是我們發現還可以輸入值,這個不是我們想要的,需要在介面設計中對ComboBox的風格設定一下:

從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

DropDownStyle改成DropDownList就可以了,看到介面上已經變灰就可以了。順道把所屬分類也一併改掉,結果就不演示了。

三、初始化所屬分類

接下來我們來實現所屬分類的ComboBox。為什麼我說所屬分類的處理要比分類型別的複雜呢?分類型別的就只有一個兩條順序的資料,而分類資料則是一個具有樹狀結構的資料,這種層次關係如何在一個下拉框中表現出來呢?

做法有也有很多種,自繪控制元件、使用第三方類庫等,考慮到初學者的教學,我就用最原始的方法:既然是樹型結構,每項資料相對於根節點就有深度,每一層深度加多幾個空格來表示,然後按父子關係排好順序,這個層次結構也就清晰了。

由於目前資料庫還沒有實現,真實資料暫時沒有,所以我們需要預先模擬一下資料,並按照分類型別繫結資料的方法編碼。至於排序,我把排序方法定義在了Model。Category中,只要我執行一下這個函式即可。程式碼如下:

從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

紅框中就是初始化所屬分類下拉框的程式碼:

listCategory是模擬的資料;

Model。Category。Sort(listCategory)是將listCategory排序;

似乎沒有什麼問題,然而執行時卻遇到一個錯誤:

從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

到網上查資料,知道問題所在了,ValueMember和DisplayMember必須指定為一個屬性值,而我宣告的Id只是一個類變數,不是屬性。我也沒搞清楚微軟為什麼要做這樣的限定,沒什麼大影響就懶得去查資料了。解決很簡單,把Id變成屬性就好了:

從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

寫成

從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

這樣再執行下來,我們就看到了:

從零開始系列,用C#做軟體產品:私人日記(九)ComboBox入門

現在,只要把排序:

cbxParent。DataSource = Model。Category。Sort(listCategory);

Model。Category。Sort函式做好,所屬分類下拉框的技術難點我們就攻克了。

如何來實現排序,下節我們繼續。

——————————————————————————

本教程儘量保證1-2天一更,專案原始碼已作為開源專案加入到Git,程式碼內容會隨教程實時更新,大家有興趣的話可以關注我,以獲得最及時的更新。私信:

私人日記

可以來獲取Git的連結。

C#基本語法大家在頭條搜尋“菜鳥c#”,個人感覺這個網站還可以。

大家閱讀過程中有哪些看不懂或未盡興的地方,可以在評論區留言,我會先記下來在後續的教程中找機會再說。

教程有幫助的話請大家幫忙關注、轉發、擴散,能不能開專欄還需要你們的支援!