本文章是由機器翻譯。

資料點

使用 Silverlight 3 和 DataForm 進行資料驗證

JOHN PAPA

建置健全的 Silverlight 應用程式,編輯,驗證資料範圍有整個許多 DataForm 控制項的問世更容易在 Silverlight 3 之間。 DataForm 控制項包含數個功能來建立允許新增、 編輯、 刪除和瀏覽的資料集的表單。 [DataForm 最大優點是其彈性] 和 [自訂] 選項。

在這個月 ’s] 欄我將示範如何 DataForm 控制項運作,以及如何它可以自訂,],然後我 ’ll 示範它的運作]。 我 ’ll 提供一個範例應用程式,使用數個功能,繫結、 瀏覽、 編輯及驗證資料,使用 [DataForm 開始。 然後我 ’ll 逐步解說的範例應用程式運作方式,時指出使用控制項和自訂建議的基本需求。 雖然 [DataAnnotations 不需要由 [DataForm,它們可能會影響外觀、 驗證方面和 [DataForm 的行為。 DataAnnotations 也可以指定自訂的驗證方法來叫用的屬性或整個實體。 我將示範如何實作在實體上的 [DataAnnotations 以及如何撰寫您自己的自訂 PAPAvalidation 方法。 這份文件的所有程式碼可以從 MSDN 程式碼庫 (msdn.microsoft.com/mag200910DataPoints) 下載。

什麼 ’s [Endgame?

之前深入進入程式碼,let’s 看一下範例應用程式的展示瀏覽]、 [驗證] 和 [編輯功能的 [DataForm。 圖 1 顯示 DataGrid 顯示員工和一個 DataForm 每個員工資料錄可以進行編輯的清單。 可以巡覽 DataGrid 的員工,變更也就目前所選的員工。 DataForm 繫結至同一組的員工,而接收的員工。

工具列

被放在編輯模式,使用者圖 1 中所示,DataForm 可變更並儲存,或取消它們。 在右上角 [DataForm 工具列會顯示圖示編輯 (鉛筆)、 加入新的記錄 (加號) 和刪除資料錄 (減號)。 這些按鈕可以樣式,並視停用。 可以藉由在 DataForm 上設定屬性自訂其可視性時,由的實體實作之介面由決定按鈕的狀態。

標籤

可以放置在 DataForm 中每個文字方塊的標題旁邊,或在控制項上方。 標籤的內容可以是中繼資料導向使用顯示 DataAnnotations 屬性。 DataAnnotations 屬性會放在的實體的屬性在這種情況下,員工的實體它們協助摘要 DataForm 資訊,如要在欄位標籤中顯示文字。

DescriptionViewer

當 [DataForm 處於編輯模式 (如的圖 1] 所示) 時,使用者可以暫留在每個文字方塊控制項,以工具提示,要在欄位中輸入項目提供的詳細資訊,請參閱旁題的旁邊圖示。 當您將 DescriptionViewer 控制項繫結的 TextBox 控制項旁邊,DataForm 被實作這項功能。 DescriptionViewer 的工具提示中顯示文字也會送從 DataAnnotations 顯示屬性。


圖 1 驗證和編輯以 DataForm

取消並認可

[取消] 按鈕,底部的 [DataForm 是在編輯模式下啟動的。 [儲存] 按鈕會啟用在編輯模式下,並在使用者變更 [DataForm 中的值。 可以自訂這些按鈕的樣式與文字。


圖 2DataForm 超出方塊

驗證通知

NotificationThe DataForm 範例中所示,使用者輸入一個無效的電子郵件地址和電話號碼中的編輯狀態。 請注意,失效的欄位的欄位標號位於紅色和文字方塊是以紅色框,以紅色標幟標示在右上角。 當使用者將游標放在失效控制項時,工具提示會出現一個訊息,描述內容已進行若要更正此問題。 圖 1 也會顯示在螢幕底部驗證錯誤的清單。 所有這些功能與 DataAnnotations DataForm 所支援,並可以使用自訂樣式來提供自訂的外觀和感覺。 驗證規則會從數個來表示例如必要的欄位或自訂規則的現成的規則 DataAnnotations 送。

設計 [DataForm

DataForm,位於 [Silverlight] 工具組,可以加入至專案一次 System.Windows.Controls.Data.DataForm.Toolkit.dll 已被參照的組件。 DataForm 可以建立非常少的安裝程式。 一次拖曳至設計介面中 Blend,或在 XAML 中建立 — 只是設為的項目集合的 [DataForm [ItemsSource — [DataForm 會自動產生欄位以顯示並啟用適當的編輯功能。 下列 XAML 會產生 [DataForm 的圖 2] 所示:

<dataFormToolkit:DataForm x:Name="dataForm" ItemsSource="{Binding Mode=OneWay}" />

注意:繫結模式設定為 OneWay 在前一個範例只為了明確。 您不需要。 但是,找它有用清晰度,以及若要明確地設定繫結模式的支援性。

其他的設定值可以被連結到 DataForm,來調整它的功能。 一般設定包括的的圖 3] 所示。

圖 3 通用 DataForm 自訂

通常,很有幫助,DataForm ’s 視覺功能,以協調它們與您的應用程式的視覺外觀的樣式。 可以使用文件]、 [app.xaml] 或 [資源字典中的資源被樣式的 [DataForm 幾個層面。 有幾個樣式可以設定中所示部分的螢幕擷取畫面中的 [圖 4 Expression 從。 請注意 CancelButtonStyle 和 [CommitButtonStyle 兩者都設定為值。 這是什麼說明按鈕藍色外觀 圖 1 在螢幕底部所示。 DataForm 本身可以是藉由設定樣式屬性的格式。 個別方面,DataForm,例如 DataField 或 ValidationSummary,也可以被樣式。

藉由設定部份的 [DataForm 這些常見屬性,以及一些基本的樣式,我們達到的圖 1] 所示的功能與外觀。 的[圖 5] 所示包含這份文件的範例應用程式設定。 請注意 AutoEdit 和自動認可兩者都設定為 false,因此要求 [DataForm 明確地放入編輯模式由使用者按一下的 [編輯] 按鈕,在 [,] 工具列上,然後使用者按一下以認可所做的變更的 [儲存] 按鈕。


圖 4 設定樣式 DataForm

表示工具列不會顯示瀏覽選項的 [CommandButtonsVisibility] 屬性中,瀏覽] 按鈕會省略的。 如果我們包含這個選項將關鍵字功能加入至 [CommandButtonsVisibility 或關鍵字來變更設定所有 [DataForm 也會顯示 [導覽] 工具列按鈕。 [CommandButtonsVisibility 屬性中包含 [認可] 和 [取消] 按鈕,因為它們會顯示。 時還不已編輯 [DataForm,[取消] 按鈕將會停用的圖 6] 所示。 瀏覽] 按鈕允許使用者移動的記錄集合。 但是,在此的範例應用程式使用者可以也巡覽使用資料繫結 DataGrid,因為它也同時為 [DataForm 同一組的資料繫結。 因此,我關閉瀏覽按鈕在工具列上完全為設計的選擇,因為瀏覽功能已經可以透過 DataGrid 來達成。

DataAnnotations

很多的 [DataForm 的功能是由 DataAnnotations 屬性放在實體資料繫結至 [DataForm 所主導的。 您參考組件 System.ComponentModel.DataAnnotations.dll,就可以使用 [DataAnnotations。 DataForm 會檢查屬性,並據此將它們套用。 圖 7 顯示數個 DataAnnotations 屬性可以裝飾的實體的屬性,並說明它們的影響。

圖 5 自訂 DataForm

<dataFormToolkit:DataForm x:Name="dataForm"
                 ItemsSource="{Binding Mode=OneWay}"
                 BorderThickness="0"
                 FontFamily="Trebuchet MS" FontSize="13.333"
                 CommitButtonContent="Save"
                 CancelButtonContent="Cancel"
                 Header="Employee Details"
                 AutoEdit="False"
                 AutoCommit="False"
                 AutoGenerateFields="True"
                 CommandButtonsVisibility="Edit, Add, Delete, Commit, Cancel"
                 CommitButtonStyle="{StaticResource ButtonStyle}"
                 CancelButtonStyle="{StaticResource ButtonStyle}"
                 DescriptionViewerPosition="BesideLabel"
                 LabelPosition="Left" />

顯示屬性摘要 DataForm ’s 標籤和 DescriptionViewer 以名稱和描述的參數分別。 如果省略,[DataForm 會自動產生使用屬性的名稱,控制項的這些值。 請注意,在圖 8 中的員工實體 ’s 名字屬性以 3 DataAnnotations 屬性裝飾。 顯示屬性表示標籤應顯示 「 名 」 的文字,且 [DescriptionViewer 應該會顯示工具提示的 「 員工 ’s 第一個名稱 」。

必要的屬性表示必須為 [名] 屬性來輸入值。 必要的屬性就像所有的驗證屬性接受一個 ErrorMessage 參數。 ErrorMessage 參數會指示在失效的控制項的工具提示和 [DataForm ValidationSummary 控制項中會顯示訊息。 StringLength 屬性為 [名] 屬性設定為表示該欄位不能超過 40 的字元,而且如果,將會顯示錯誤訊息。

圖 8] 中的程式碼顯示當已在屬性上設定值,驗證方法會叫用。 驗證是基底類別 ModelBase 我用來在這個範例中的所有項目中建立的方法。 這個方法會驗證藉由檢查它對其 DataAnnotations 屬性的所有屬性。 將如果其中的任何失敗,它會擲回例外狀況、 不該屬性設定為無效的值],並指示來通知使用者 DataForm。 圖 1 顯示清空 [名字] 欄位,因為它是必要的結果。

讓每個屬性可以設定時驗證會在每個屬性 setter ModelBase 類別 ’s 驗證方法叫用。 此方法可接受新的值以及正在驗證之屬性的名稱。 這些參數依序傳遞至驗證程式類別 ’s ValidateProperty 方法不會實際驗證屬性值:

protected void Validate(object value,
string propertyName) {
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) {
MemberName = propertyName });
}

在驗證器是靜態類別,可讓您執行驗證,使用數個不同的技術:

  • ValidateProperty 方法會檢查單一屬性的值,並會擲回 DataAnnotations.ValidationException,如果值是不正確。
  • ValidateObject 方法會檢查整個實體上的所有屬性,並會擲回 DataAnnotations.ValidationException,如果任何值無效。
  • TryValidateProperty 方法除了傳回布林值的值,而不是擲回例外狀況則傳回用來執行 ValidateProperty,為相同的驗證檢查。
  • TryValidateObject 方法除了傳回布林值的值,而不是擲回例外狀況則傳回用來執行 ValidateObject,為相同的驗證檢查。
  • ValidateValue 方法接受數值,並驗證屬性的集合。 如果值失敗任一屬性,會擲回一個 ValidationException。
  • TryValidateValue 方法執行 ValidateValue,為相同的驗證檢查,但它會傳回布林值而非擲回例外狀況。

圖 7 通用 DataAnnotations

圖 8 名字屬性以 DataAnnotations

private string firstName;
[Required(ErrorMessage = "Required field")]
[StringLength(40, ErrorMessage = "Cannot exceed 40")]
[Display(Name = "First Name", Description = "Employee's first name")]
public string FirstName
{
get { return firstName; }
set
{
if (firstName == value) return;
var propertyName = "FirstName";
Validate(value, propertyName);
firstName = value;
FirePropertyChanged(propertyName);
}
}

我也會建立名為的呼叫 TryValidateObject 方法,如下所示的 IsValid ModelBase 類別中的方法。 這個方法可以被呼叫實體上在任何時候以判斷它是否在有效的狀態:

public bool IsValid() {
return Validator.TryValidateObject(this,
new ValidationContext(this, null, null),
this.validationResults, true);
}

圖 9 的自訂屬性的驗證

public static class EmployeeValidator
{
public static ValidationResult ValidateAge(int age)
{
if (age > 150)
return new ValidationResult("Employee's age must be under 150.");
else if (age <= 0)
return new ValidationResult(
"Employee's age must be greater than 0.");
else
return ValidationResult.Success;
}
}

自訂驗證

當一個現成的屬性,從 DataAnnotations 一組不會夠了時,您可以建立自訂的驗證方法,和將它套用至整個物件或屬性值。 驗證方法必須是靜態,且傳回 ValidationResult 物件。 ValidationResult 物件是包含訊息將會繫結至 [DataForm 車輛。 圖 9 顯示驗證值介於 0 到 150 ValidateAge 自訂的驗證方法。 這是一個簡單的範例,而且可能已使用 Range 屬性。 但是,建立特定的方法可以讓它由多個驗證的項目重複使用。

也可以驗證整個物件,建立自訂的驗證方法。 ValidateEmployee 方法接受整個員工實體,並會檢查幾個屬性在判斷實體處於有效狀態。 這是強制使用實體層級驗證,很有幫助,如下所示:

public static ValidationResult ValidateEmployee(Employee emp) {
string[] memberNames = new string[] { "Age", "AnnualSalary" };
if (emp.Age >= 50 && emp.AnnualSalary < 50000)
return new ValidationResult(
"Employee is over 50 and must make more than $50,000.",
memberNames);
else
return ValidationResult.Success;
}

[DataForm 一或多個 ValidationExceptions 擲回 (請參閱的圖 10]) 時,會顯示驗證摘要控制項。 欄位的名稱會以粗體字母旁邊顯示驗證訊息時醒目提示。 如果想要在 ValidationSummary 樣式也可以自訂要使用一個的資源。


圖 10 驗證摘要

influencers

DataForm 採用其提示,從 DataAnnotations 以及從其繫結的資料來源實作的介面。 就例如員工實體實作 IEditableObject 介面。 這個介面會強制由 [DataForm 在叫用適當的時間編輯 [DataForm 時將 BeginEdit CancelEdit,EndEdit 方法的實作。 在的範例應用程式我來這些方法執行取消行為,所以使用者可以按 [取消] 按鈕,並還原原始的實體值。

這種行為是建立 BeginEdit 方法 (命名的快取) 中的實體的執行個體,並從實體複製原始值來達成。 CancelEdit 方法複製所有的值表單快取實體回到在原始實體因此還原原來的狀態時,EndEdit 方法會清除快取物件。

當 [DataForm 看到它繫結至集合的一個 CollectionViewSource 時,它將會支援編輯、 排序、 篩選及追蹤目前的記錄 (也就是貨幣)。 它也可確保 [DataForm 並不允許使用者瀏覽離開為無效的實體狀態,而不需要修正它並認可或取消所做的變更是重要,「 貨幣 」 功能。 繫結至一個 PagedCollectionView 的 [DataForm 也提供這些相同的功能,並也提供 [刪除的項目、 加入項目和群組項目。 繫結至的 ObservableCollection 會停用一些這些的功能,自行在 ObservableCollection 未實作介面,[DataForm 看起來的。

如果您的實體已經當中的 ObservableCollection,您可以建立一個 PagedCollectionView ObservableCollection 執行個體傳遞至集合,透過它的建構函式如下所示:

var employees = new DataService().GetPeople();
PagedCollectionView view = new PagedCollectionView(employees);
this.DataContext = view;

或者,您可以建立一個 CollectionViewSource 藉由傳遞的員工,ObservableCollection 到 CollectionViewSource ’s 集合初始設定式,並設定 [來源] 屬性,如下所示:

var employees = new DataService().GetPeople();
CollectionViewSource view = new CollectionViewSource
{Source = employees};
this.DataContext = view;

總結

DataForm 將大量的值,應用程式和瀏覽、 編輯和檢視資料的一般密集的程式碼和 monotonous 程序。 它的功能是可自訂以符合您的需求,而且它可以樣式以視覺方式來混合您的應用程式 ’s 設計的。

John Papa (johnpapa.net) 是資深的顧問棒球風扇花費夏天住宿為根建立 [Yankees 與他的家人的人員。 papa 在 Silverlight MVP Silverlight 高手,INETA 演講者,已撰寫包括他的最新的幾個書籍 「 資料導向的 Silverlight 2 的服務 」 (O’Reilly 2009)。 他通常講話演說例如 VSLive!,DevConnections 和 MIX。