高級綁定功能
轉換器
轉換器允許您動態地轉換可綁定的屬性值。
默認轉換器
DevExpress MVVM框架自動管理簡單的類型轉換,例如在通過默認轉換器綁定的演示中,字符串TextEdit.Text屬性被綁定到整數ViewModel Progress屬性,在這里框架將屬性值從Int32轉換為String并返回。
C#:
//View code var fluent = mvvmContext.OfType<ViewModel>(); fluent.SetBinding(editor, e => e.Text, x => x.Progress); //ViewModel code public class ViewModel { public virtual int Progress { get; set; } }
VB.NET:
'View code Dim fluent = mvvmContext.OfType(Of ViewModel)() fluent.SetBinding(editor, Function(e) e.Text, Function(x) x.Progress) 'ViewModel code Public Class ViewModel Public Overridable Property Progress() As Integer End Class
當框架轉換值時,MvvmContext組件會觸發BindingConvert事件。您可以處理此事件來調整轉換邏輯,綁定自定義轉換處理演示演示了一個texttedit編輯器,它的EditValue屬性綁定到整數ViewModel Value屬性。如果用戶讓textit為空,則編輯器的EditValue為null,因為自動轉換不能將null轉換為Int32,在這種情況下,使用BindingConvert事件處理程序將null更改為0。
C#:
//View code var fluent = mvvmContext.OfType<ViewModel>(); mvvmContext.BindingConvert += (s, e) => { string strValue = e.Value as string; if(strValue != null) { int intValue; if(int.TryParse(strValue, out intValue)) e.Value = intValue; else e.Value = null; } if(e.Value == null) e.Value = 0; }; fluent.SetBinding(editor, e => e.EditValue, x => x.Value);
VB.NET:
'View code Dim fluent = mvvmContext.OfType(Of ViewModel)() AddHandler mvvmContext.BindingConvert, Sub(s, e) Dim strValue As String = TryCast(e.Value, String) If strValue IsNot Nothing Then Dim intValue As Integer = Nothing If Integer.TryParse(strValue, intValue) Then e.Value = intValue Else e.Value = Nothing End If End If If e.Value Is Nothing Then e.Value = 0 End If End Sub fluent.SetBinding(editor, Function(e) e.EditValue, Function(x) x.Value)
自定義轉換器
當使用不能自動轉換的復雜屬性類型時,需要傳遞兩個轉換器作為最后一個SetBinding方法參數。第一個轉換器將可綁定的屬性值轉換為可接受的類型,第二個轉換器則相反。
通過自定義轉換器進行綁定演示演示了一個帶有ModelState屬性的ViewModel,該屬性接受自定義狀態枚舉值,此屬性綁定到CheckBox.CheckState屬性,其類型為System.Windows.Forms.CheckState,SetBinding方法中的Lambda表達式是轉換屬性值的轉換器。
C#:
//View code var fluent = mvvmContext.OfType<ViewModel>(); fluent.SetBinding(check, e => e.CheckState, x => x.ModelState, modelState => { // Convert the ViewModel.State to CheckState switch(modelState) { case ViewModel.State.Active: return CheckState.Checked; case ViewModel.State.Inactive: return CheckState.Unchecked; default: return CheckState.Indeterminate; } }, checkState => { // Convert back from CheckState to the ViewModel.State switch(checkState) { case CheckState.Checked: return ViewModel.State.Active; case CheckState.Unchecked: return ViewModel.State.Inactive; default: return ViewModel.State.Suspended; } }); //ViewModel code public class ViewModel { public virtual State ModelState { get; set; } public enum State { Suspended = 0, Inactive = 1, Active = 2 } }
VB.NET:
Dim fluent = mvvmContext.OfType(Of ViewModel)() fluent.SetBinding(check, Function(e) e.CheckState, Function(x) x.ModelState, Function(modelState) Select Case modelState Case ViewModel.State.Active Return CheckState.Checked Case ViewModel.State.Inactive Return CheckState.Unchecked Case Else Return CheckState.Indeterminate End Select End Function, Function(checkState) Select Case checkState Case CheckState.Checked Return ViewModel.State.Active Case CheckState.Unchecked Return ViewModel.State.Inactive Case Else Return ViewModel.State.Suspended End Select End Function) 'ViewModel code Public Class ViewModel Public Overridable Property ModelState() As State Public Enum State Suspended = 0 Inactive = 1 Active = 2 End Enum End Class
如果不允許用戶編輯View元素的屬性值,則可以跳過反向轉換。
格式化綁定值
要格式化綁定的屬性值,請將字符串格式表達式傳遞給SetBinding方法,{0}字符序列是屬性值的占位符。
C#:
var fluent = mvvmContext.OfType<ViewModel>(); fluent.SetBinding(labelControl, l => l.Text, x => x.Value, "Bound property value is ({0})");
VB.NET:
Dim fluent = mvvmContext.OfType(Of ViewModel)() fluent.SetBinding(labelControl, Function(l) l.Text, Function(x) x.Value, "Bound property value is ({0})")
可以添加來應用其他數字、 date-time和時間跨度格式,MVVM最佳實踐演示演示了如何將整數值顯示為貨幣。
C#:
var fluent = mvvmContext.OfType<ViewModel>(); fluent.SetBinding(label, l => l.Text, x => x.Price, "Price: {0:C2}");
VB.NET:
Dim fluent = mvvmContext.OfType(Of ViewModel)() fluent.SetBinding(label, Function(l) l.Text, Function(x) x.Price, "Price: {0:C2}")
將多個屬性綁定到同一個控件
要組合同一控件中的多個屬性值,請使用MvvmContext.SetMultiBinding方法,這個方法接受以下參數:
- 控件名稱。
- 應該被綁定的控件屬性。
- 一個字符串數組,其中包含可綁定的ViewModel屬性的名稱,這些屬性的值應該組合在一起。
- 格式字符串(對于不可編輯控件)或一對轉換器(如果允許用戶編輯綁定控件)。
DevExpress演示中心提供了兩個模塊,它們將FirstName和LastName屬性的值組合到一個textit編輯器中。使用格式字符串的模塊將屬性綁定到禁用的(不可編輯的)編輯器,在使用轉換器的模塊中,您可以更改TextEdit值并將更新后的字符串傳遞回ViewModel屬性。
- 格式化字符串演示
C#:
var fluent = mvvmContext.OfType<ViewModel>(); mvvmContext.SetMultiBinding( editForFullName, e => e.Text, new string[] { "FirstName", "LastName" }, "{1}, {0}" );
VB.NET:
Dim fluent = mvvmContext.OfType(Of ViewModel)() mvvmContext.SetMultiBinding(editForFullName, Function(e) e.Text, New String() { "FirstName", "LastName" }, "{1}, {0}")
- 轉換器演示
C#:
var fluent = mvvmContext.OfType<ViewModel>(); mvvmContext.SetMultiBinding( editForFullName, e => e.EditValue, new string[] { "FirstName", "LastName" }, values => string.Join(",", values), value => ((string)value).Split(',') );
VB.NET:
Dim fluent = mvvmContext.OfType(Of ViewModel)() mvvmContext.SetMultiBinding( editForFullName, Function(e) e.EditValue, New String() { "FirstName", "LastName" }, Function(values) String.Join(",", values), Function(value) CStr(value).Split(","c))