[Excalibur]ASP.NET MVVM - ValueConverter

ValueConverter 物件型別轉換處理類別

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

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


<%@ Register Src="UserControl2.ascx" TagName="UserControl2" TagPrefix="uc1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>ValueConverter</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <uc1:UserControl2 ID="ViewModel" runat="server" />
            <asp:TextBox ID="TextBox1" runat="server" AutoPostBack="true" MaxLength="1"
                Text='<%$ Binding : Word %>'></asp:TextBox>
            <br />
            ASCII:
            <asp:Label ID="Label2" runat="server" Text='<%$ Binding : Mode = OneWay , GetNumber %>'></asp:Label>
        </div>
    </form>
</body>
</html>

public class ASCIINumberValueConverter : ValueConverterBase
{
    public ASCIINumberValueConverter(Type propertyType)
        : base(propertyType)
    {

    }
    public override object Convert(object value, out bool done)
    {
        try
        {
            value = System.Convert.ToChar(value);
            done = true;
            return System.Convert.ChangeType(value, this.PropertyType);
        }
        catch { }
        done = false;
        return value;
    }
    public override object ConvertBack(object value, Type targetType, out bool done)
    {
        try
        {
            value = System.Convert.ToChar(value);
            done = true;
            return System.Convert.ChangeType(value, targetType);
        }
        catch { }
        done = false;
        return value;
    }
}


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指出是否成功轉換


public partial class UserControl2 : Extensions.Web.UI.UserControl
{
    [ViewStateProperty(65)]
    [ValueConverter(typeof(ASCIINumberValueConverter))]
    public int Word { get; set; }
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    public int GetNumber()
    {
        return Word;
    }
}

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

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