從無到有建立 VariableSizedWrapGrid – 用 Blend 實作 Jerry 的範例

全程用 Blend 從無到有實作 VariableSizedWrapGrid

 

要有求甚解的精神

目前 VariableSizedWrapGrid 實作上就屬 Jerry Nixon 的最讚!

更棒的是還錄好了完整影片可以讓大家知道整個實作的來龍去脈 (太佛心了)

http://blog.jerrynixon.com/2012/08/windows-8-beauty-tip-using.html

 

但影片中全程都是用 Hard Code 的方式建立 XAML Code

為了弄懂所有的過程除了自行實作一次外 ( 包含玩弄它 )

還特地全程改用 Blend 自已實作一遍,並且符合「Style 的規範 」

確認套版沒問題後,再實作一次到 Group Template 上  (成果如下)

http://www.dotblogs.com.tw/franma/archive/2012/10/07/76299.aspx

 

其效果非常地好,雖然花了點時間。卻可以讓我在各種不同的情況中了解問題

所以在團隊中就算案子趕到靠杯,還是要有求甚解的精神。才不會遇到問題改不出來慘案發生

畢竟在實務上的問題百百種

 

另外若是團隊正在要入門 Win 8 App 且又對 XAML 沒那麼熟悉的話

建議還是先從 Blend 開始學習,先了解 XAML 架構後再切回到 XAML Code

學習門檻也會比較低一些 ,當然工具的學習還是一定要有的。 

 

以下所有的動作皆是依照文章的項目實作的

 

先準備好資料

用 VS 2012 開啟一個空白的 Win 8 Store App

再建立一個 Class 這裡是取名為 SampleDataSource.cs

 

Sample Data 就沒有什麼特別的,一樣就是要自已 coding

但這裡是用範本的規範來寫

 

image

 

image

 

image

若是有定好 DTO Class 那這裡就會有 IntelliSense 支援

 

image

指定每個欄位的內容,至於 ProperyInfo.GetValue 為什麼要 Null 則是因為非 index 

可以參考 MSDN http://msdn.microsoft.com/zh-tw/library/b05d59ty.aspx

至於最後再轉型成 List 是因應 XAML 和 Blend 可以支援的規格 ( 雖然 IEnumerable 也可以,但在 Blend 中就無法正常 Binding )

 

image

要讓程式取得資料,所以再增加一個 GetData Method

 

確保我們剛剛寫的項目無誤,現在用 Blend 將資料 binding 到 GridView 去看看

 

Bind 到 GridView

image

直接用 Blend 開啟,接下來所有的介面都是用 Blend

image

這裡是要用 GridView 以「滿版」的方式呈現,所以將 Gridview 拉到畫面上後,拉跟畫面一樣大並且在四周的「鎖鍊」都要鎖起來。

這樣子不管什麼解析度,GridView 都會跟著放大縮小。

 

image

在根目錄上選擇 DataContext

image

這時就選擇剛剛建立的 SampleDataSource

在 Win8 中所有的介面 DataBinding 建議的做法其實是會透過 CollectionViewMode 來處理 ( MVVM 機制的 VM 這一段 )

用這樣子的方式處理除了不用自已手動的方式更新介面外,在 Blend 更可以「所見即所得」的方式編輯畫面

 

image

DataContext 建立好之後,就要和 GridView 建立 DataBinding 的關係

image

選擇 GetData 可以看到它吐回 ColorItem ,沒錯這就是我們要的。

( 若是用 Var 的話就什麼都看不到,用 IEnumerable 的話也會不太正常 )

image

Binding 無誤的話,應該會出現這個畫面後就代表剛剛寫的 Linq 語法正確啦!

 

GridView Item 的 介面調整

為了讓 Item 可以正常顯示顏色,所以我們要設定 Item 要 Bind 什麼內容和項目

image

第一件事就是建立 Item Template ( 您可以把這個想像成 HTML 的 CSS )

image

建議正規的作法應該要放在資源字典中,並且取一個好聽又有規範的名稱 ( 請不要縮寫 )

image

設定 Grid 的大小

image

Binding 顏色

image

選擇 Color 項目

image

重新編譯後就可以看到顏色可以正常Binding 到畫面上了

 

image

加上 TextBlock 並放到 Grid 群組中。在 Grid 的背景設定黑色並且半透明 75%

而 TextBlock 的 Text 依剛剛顏色的方式 Binding Name 的欄位即可

 

image

是不是很簡單很容易上手!

 

正式的來了 VariableSizeWarpGrid

 

接下來的動作主要關鍵的地方在之前的文章都已經有提了,這裡只會注重在當初轉換blend 的地方

http://www.dotblogs.com.tw/franma/archive/2012/10/07/76299.aspx

 

image

回到 VS 中將 語法修改成如上,為了可以知道目前 Item 的順序編號,所以加上了 index

而 ColSpan 當然是為了可以知道它要跨幾欄, Item Height  則是為了 Style 的 Layout 可以跟著變大

 

Select 的 (x , I )的第二個參數為什麼會是 index 號碼

詳細的說明這裡有寫 http://msdn.microsoft.com/zh-tw/library/bb534869.aspx 

 

 

讓 Item 的大小可以跟著跨欄放大

image

這裡是跨欄是否能讓「樣版」正確顯示的絕對性關鍵 ( 此步驟在原來的文章中並沒有 )

當然也多加了一個 TextBlock 去Binding Index ,或是用 <Run> 來區分也是不錯的做法。

image

分別是此兩個欄位 ( 此數值是動態計算的,請不要寫死 )

之前有看到客戶的專案是直接寫死的,結果在判斷上還要更換 Template 那以後樣式要換時,豈不是搞自已嗎?

 

變更為 VariableSizedWarpGrid 的 ItemPanel

若是自已拉出來的 GridView 其預設都是用 WarpGrid 當做預設的 Item Panel

image

因為我們要讓 Item 可以動態跨欄,所以要改用 VariableSizedWarpGrid

image

 

image

這裡是決定 Grid Item 最小單位的長寬,若是沒有設定的話會造成 跨欄的 Style 無法正常顯示

到目前為止畫面上就告一個段落

 

image

為了讓 VariableSizedWarpGrid 可以處理跨欄問題,這裡就必須要「覆寫」PrepareContainerForItemOverride

其實這裡我有花了很多時間去試能不能不要另外再產生 MyGrid ,也能達到同樣的效果。但目前沒有比這個更好的做法了

 

image

重新編譯後再執行一次

image

跑起來的效果應該當都會跟原來的一模一樣。

 

決定那些欄位要跨欄

有看到一些專案會在 PrepareContainerForItemOverride 中直接寫死說那個 Item 載入時要用多大 或是 那個 Template

但這樣子的寫法並不是很健康,因為決定是否跨欄並該由 Data 那一端就決定,而不是到畫面上時才判斷

image

我們決定要 1 號可以長、寬都跨 2 個

image

顯示的效果就會是如上,這樣子就大功告成啦!!

是不是幾乎都沒有寫到什麼程式碼,也幾乎不用去改 XAML Code 。

而且產生出來的 XAML Code 都可以很容易讓 UI 設計師單獨去調整畫面

 

更重要的是,當你的團隊有兩個人想要協同運作一人Coding 另一人改畫面的話

唯獨這樣子的做法是最快的,而且畫面也不會拉錯不對齊 ( 不對齊一律都會被退件的 )

 

文字說明框不想要被拉長

剛剛可以看到 當 編號 1 有跨欄時其「說明框」整個就是被拉高的,若想要唯持原來的高度的話

那麼就要再回到「Item Template」那裡去修改,將

image

 

這裡只要調整 上面的鎖鍊「解開」後,就馬上可以看到 1 號的 Layout 就會是跟著下面對齊了

image

 

若是自已改 XAML 的話就要一個一個調 Margin 。