這陣子在趕一個小案子,目標是在網頁中實做一個可以凍結標題欄/列,可以任意調整欄寬、順序,並可以排序的大型資料表。

大家應該記憶猶新,不久前我才發表過GridView的標題欄、列凍結效果(跨瀏覽器版),其實為的也是同一個案子。不過評估之後,網頁版如果要加上用滑鼠拖拉調整欄位寬度、順序及動態排序的功能,若自己動手改,寫到牙歪了還不見得流暢無誤;找現成的商用WebControl元件也是解法,但考量這個資料表被用來監控大量數據的持續變化(跟股市看盤畫面有點類似),試了一下,光用HTML Table列出這麼龐大的矩陣就讓瀏覽器汗流浹背了,更甭提捲動時畫面慢如老牛拖車,我認為改用商用元件也不會太樂觀。

最後我做了個勇敢的決定 -- 就讓Silverlight試試身手吧! (現在想想,第一個Silverlight專案不是做紅綠燈或影片播放器,而是直接硬幹應用程式操作UI,真是不知死活藝高人膽大。)

Silverlight 2.0終於有了Datagrid Control,是讓我敢大膽嘗試的主要原因,內建凍結標題功能、可自由調整欄位寬度、順序,只要Bind上資料物件,物件屬性一改,顯示的數字就會自動改變(但別忘了實作INotifyPropertyChanged!),架構完整單純,比起在HTML中硬幹,省事許多。

不過,用真實的專案"邊做邊做"Silverlight 2.0,"非常"具有挑戰性,最棘手的部分莫過於Silverlight Datagrid的應用普遍性偏低,不管是坊間書籍或網路案例都著墨都不多,加上對Silverlight 2.0的基本認識如一片白紙,一路創下許多可觀記錄:

  • 依條件改變DataRow底色 --> 耗時4小時
  • 在DataRow間加入間隔線 --> 耗時3小時
  • 依正負值切換不同DataCell底色 --> 耗時1小時
  • 在ListBox上加上DoubleClick事件 --> 耗時10分鐘

這些寫網頁時原本要"秒殺"的任務,居然都變成以小時計,還深怕自己想出的解法是在繞遠路,極不習慣。感覺自己像是忽然中風癱瘓,連伸手拿杯水喝都要抖著手掙扎半天,搞到滿身大汗才能如願。但值得欣慰的是,解決問題所花的時間愈來愈短,算是漸入佳境。

流血流汗數日,雛型大致完成。一方面丟給User試用,另一方面也回頭做Refactoring。結果遇到有趣的問題,在Visual Studio 2008改完程式要去Blend2編輯UserControl時,出現以下錯誤。

同一個XAML在VS2008中可以正確預覽,實際執行也無誤,就只有在Blend2無法產生Design View(XAML View正常)。原本以為是XAML裡某個語法Blend2不吃,後來看了錯誤訊息中的StackTrace恍然大悟! 原來是程式會將使用者上回調整的欄位資料寫入IsolatedStorage,下回啟動時自動讀入還原。結果這段程式在Blend2中居然會被執行(在UserControl_Loaded中),Blend2中的環境當然不會跟網頁完全相同,因此出錯。

解決方法很簡單,之前在.NET 2.0裡有過判別DesignMode避開特定邏輯的經驗,這回如法泡製即可。我找到一篇文章,介紹用DesignerProperties.GetIsInDesignMode(Application.Current.RootVisual)就可以做出如.NET 2.0 DesignMode屬性的效果。

避開只有在Web中才適用的邏輯,問題解決!


Comments

# by brian

真棒, 可能要等silverlight3+.NET RIA service後會更好用吧. 是否可以分享一下代碼呢?

# by Christopher

你好,請問你在這專案有實做datagrid欄位右鍵事件嗎?謝謝。

# by Jeffrey

to Christopher, 這專案沒用到右鍵。據我了解,Silverlight把右鍵的操縱主導權留給了Browser,如果要實作,得由Javascript onmousedown事件下手,由JS與Sliverlight聯手完成。

# by Christopher

不好意思再請教你一個問題,如果使用你說的這種方式,DataGrid能夠做到像HTML的Table被按下右鍵時,抓到是哪個Cell被按下右鍵,然後變換這個Cell的Style並依內容來處理嗎?謝謝。

# by Jeffrey

to Christopher, 沒仔細研究過,給個不負責任的點子: 可以用Sivlerlight的onmouseover隨時記錄滑鼠座標,當JS端onmousedown時再回頭查詢當下的滑鼠所在去找出Cell。這是我目前想到的解法,若有其他高手前輩有相關經驗,也請賜教。

# by Christopher

謝謝你的建議,也不好意思請教了你這麼多問題。

Post a comment


89 - 41 =