2013年10月6日 星期日

ASP.NET MVVM - 兩個Extensions UserControl互動與相互傳值的方法

如果常在WebForm應用程式中切割一堆UserControl使用
難免會碰上互動傳值的問題,而且解法應該不少
普通情況只要頁面上有Register過ascx路徑都可以取得類別型態與Property/Event
然後也能利用FindControl和Interface來處理...等等
但若是兩個UserControl放置在千里之遙
甚至不在氣泡事件OnBubbleEvent能解決的樣版關係的情況下
可以試試以下設計的方法






SendMessage方法傳送的第一個參數即MessageNotify事件EventArgs的CommandName
第二個參數即事件EventArgs的CommandArgument
MessageNotify中的sender則是發送訊息的UserControl物件

這裡呼叫SendMessage會對Page內所有Extensions UserControl註冊的MessageNotify事件進行觸發
但是不會觸發發送訊息的UserControl自己本身註冊的MessageNotify事件
所以也能在MessageNotify事件時呼叫SendMessage傳送其他訊息出去

 (MVVM 1.1.1.8版本以上加入)

後記:在更新版本中加入了Attribute的使用方法,示例中的UserControl2可改寫成這樣

相當於直接標註方法為可讓其他控制項以SendMessage公開呼叫的意思
呼叫的Command為指定的方法名稱,Argument為參數

2013年9月25日 星期三

ASP.NET MVVM - ExtensionsControl (2)

這次MVVM更新到1.1.1.5版了,那這裡要介紹的新控制項是RouteManager跟HolderSource
顧名思義第一個控制項八成是用來搞Url的Route用的
第二個也一定和PlaceHolder用來動態載入控制項的功能有關

首先要使用RouteManager因為要用到ASP.NET 4.0才加入的Route功能,需要在Global.asax中設定
假設網站首頁的路徑是"~/Default.aspx"那麼Application_Start中就加入以下程式


前兩行是排除不需改變Route規則的Url,然後只要將"~/Default.aspx"
傳入RouteManager的Configure方法即可
接著就新增首頁的Default.aspx檔案

在Default.aspx的頁面中加入RouteManager與HolderSource控制項
其中HolderSource可同時放入多個並且可以在部分HolderSource的HolderTemplate樣板中
能再放入一層的單個RouteManager加多個HolderSource的組合,之後數層的規則一樣
例如就像下面這樣具有到第三層的樹狀排列結構


這樣就完成可以執行測試了

RouteManager中只有一個DefaultLoadName屬性可以用來選擇RouteValue
不符時預設顯示的HolderSource的ID
然後HolderSource的ID則就是被用來與Url之中當RouteValue比對
HolderSourceID與RouteValue相符就會顯示HolderTemplate的內容
比如說瀏覽器網址是"http://localhost:25179/Index/"
在上面的例子就會呈現Index這個HolderSource的樣板內容
若網址導到是"http://localhost:25179/Home/"
Index的樣板就不會呈現而改成呈現Home的樣版內容
如果網址後面多加一個目錄變成"http://localhost:25179/Home/Page1/"
那麼除了呈現Home的樣版內容外還會讓Home中Page1的樣版內容也一起呈現出來
依此類推,這樣我們就可以利用Route控制網頁中控制項的呈現





HolderSource也有個IsLoad屬性預設值是false用來控制樣版呈現,當樣版內容不呈現時
不管裡面被放什麼控制項都不會被載入跟進入生命周期事件那麻煩的ViewState也就不會產生了
RouteManager的工作就只是用Route物件比對Url,先算出自己在哪一層
再找出應該要用來呈現的HolderSource將IsLoad變成true而已
而且因為樣板裡面也能夠放入UserControl那些
所以也可以視情況在UserControl中選擇再放入RouteManager與HolderSource進去
只要總共不要超過10個的RouteValue就應該沒有問題了吧

2013年9月15日 星期日

技術的堅持和原則重要嗎?

關於到底重不重要這個問題我覺得真的沒有很重要耶
因為我覺得就算說多重要很多時候也只是被拿來說說而已
否則我們也不會有這麼多有關技術債留下的難題了
例如我就遇到過的:
a.一個網頁表單的aspx.cs會出現包山包海的數千行程式碼(神物件)
b.單一個存表單資料的資料表欄位能多達上百欄(反正規化?)
c.某個App_Code中的套印類別居然用上三維陣列(可能在實做什麼演算法吧)
d.網站首頁被放入複雜sql統計無cache直到有天流量尖峰使用者無法登入
e.網站登入資訊頁在Page_Load直接呼叫外站服務無例外處理讓網站隨外站一起掛
f.到處都是的SQL Injection弱點(真的可以執行sp_MsForEachTable逞罰)
g.同事網站的登入資訊居然用靜態變數儲存,上線自己還抓不到BUG
h.還有更多萬能的Session在控制項的事件中設定與讀取
...
還有許多,這些要列是列不完的
有句話說"知識是有限的,只有愚蠢才是無限的"大概就是形容這些。
但是我們也不能否認在獲得知識前無知的自己大概也曾經犯下過錯(或臨時的發蠢狀態XD)
差別在每個人蠢的時間長度不同,有些人真的是橫寫的阿拉伯數字八阿

可是這邊就產生了更奇怪的問題,而且對我們也許可能更加的重要
"解決這些技術債的問題算聰明還是愚蠢呢?"
我認為會有這些問題時表示技術的重要性已經有很大程度的被無視了
這時候應該要考慮的是"你自己的位置"
Position Yourself(http://st-threath.blogspot.tw/2013/09/position-yourself.html)
其實我是想分享這篇文章
當技術在你身上,而你在這個地方(黑人騎馬真得很奇怪?...)
會不會使你變得強勢還是繼續的弱勢你真的要想清楚

以前我曾經有件任務要去修改一個ClassLibrary1.exe的專案
這隻是個定期從外站服務撈取資料然後轉換存進系統資料庫的排程程式而已
需要我在裡面加上在存進資料的同時過濾出可疑資料自動發信email給使用者的功能
沒錯...這個專案名稱就是ClassLibrary1,新增類別庫專案時的預設名子(然後專案屬性被改成執行檔)
可想而知裡面的程式碼根本無法維護,要不就是我能力太差吧
沒有辦法,那時我就只好花了超出預定一點的時間去整個重寫這隻程式(不只是換個好名子啦XD)
後來也只是被主管問到是不是程式重寫了而已,感覺不出很在意為什麼的樣子
不過我也沒去多想...當然後來在那間公司還是有發生很多其他事情
最後也離開了那裡,和那間公司最後的關係就是互相的逞罰吧...
至於現在的我多少了解到關於真正的問題是出在哪裡

我們不應該留在視對技術的堅持和原則為愚蠢的地方
更重要的是要能更快的去查覺自己的位置、關於技術是被怎樣看待的
自己的機會會在哪裡、是否有什麼方法可以改變它,那些多少都是有跡可循的(不知道就google公司名稱阿XD)
又或者你的判斷是因為在其他地方有利所以可以讓步無所謂也罷
最怕的是什麼都沒想,沒發現自己處在不允許任何堅持的劣勢
那時再問對技術的原則與堅持重要嗎?
吼,我自己舉自己的例子都覺得有點丟臉了啦>///<

2013年8月27日 星期二

ASP.NET MVVM - ExtensionsControl (1)

這兩天在ASP.NET MVVM Excalibur中加入了幾個使用者控制項
我一直在想有無好一點的方法去處理ViewModel對陣列集合資料的繫結功能
結果還是先把平日自己開發來經常使用在集合資料的控制項加進去了
以下是對這幾個控制項的介紹與示例程式

首先是FreeDataSource跟Pagination的功能

1.FreeDataSource是一個資料來源控制項如同SqlDataSource,ObjectDataSource,EntityDataSource等一樣 用來搭配ListView,GridView,DataList..等等控制項呈現資料
其特性是沒有其他限制,讓我們可以直接使用事件的回傳值當作資料來源
無論在方法中回傳什麼也都盡可能讓它能支援分頁排序等功能
例如下面的方法:
就能直接讓回傳的IEnumerable物件資料用做DataBind的資料這樣

2.Pagination是分頁用的控制項搭配FreeDataSource與DataPager製作分頁功能
使用時需要在Pagination上指定PagerControlID以及在FreeDataSource上將PaginationControlID
設定為該Pagination的ID


執行結果:

順利完成分頁
(其實還可以在FreeDataSource的方法中透過取得的頁數進行分頁處理)

這裡主要是想當我們使用MVVM時可以讓ViewModel使用Binding去繫結FreeDataSource的OnExecuteSelected事件,然後就能將資料DataBind到要顯示資料的ListView或GridView上面,
以達到控制Model資料的權責歸於ViewModel,與View的呈現邏輯分離

另外還有加入PluralHolder, ContainerButton, HolderSource三個控制項
是有關於控制動態樣板的功能,在編輯多筆資料時也許有用
與示範程式一併都放在1.1.1.3版以後的專案範本中

2013年1月22日 星期二

ASP.NET MVVM - ValueConverter


最近MVVM新增的功能是關於Binding屬性(Property)間物件型別轉換的處理
過去我們只是利用IConvertible介面在背後做簡易的轉換
這在Web上沒有太大的問題,資料大多都為字串也就一直都沒處理例外
只是最好的方式還是ViewModel與View上控制項屬性使用完全相同的屬性型別
不過今天新增了一個抽像類別ValueConverterBase
可以在當我們開發ViewModel時選擇為屬性(Property)添加Attribute
指定特定的ValueConverter轉換類別去處理型別轉換問題
(當然沒有指定Attribute的屬性我們還是有利用IConvertible處理預設型別轉換)

以下是一個轉換屬性型別的範例
當介面上TextBox輸入一個字元時,Binding到ViewModel可以轉成該字元ASCII號碼的int型態





ASCIINumberValueConverter實做了ValueConverterBase中的兩個函式

Convert(object value, out bool done)
將傳入的value轉換成ViewModel所要的屬性型別(PropertyType),out done指出是否成功轉換

ConvertBack(object value, Type targetType, out bool done)
將傳入的value轉換回View上控制項原本的屬性型別(targetType),out done指出是否成功轉換


在屬性上設定ValueConverterAttribute由ASCIINumberValueConverter
來處理Word這個屬性的型別轉換

(附帶一提,ViewStateProperty是讓這屬性存放到ViewState中,65是預設值)