介面控制元件DevExpress WPF入門指南:MVVM 框架 - BindableBase
BindableBase類實現 INotifyPropertyChanged 介面,並提供 API 以最少的編碼宣告可繫結屬性。
可繫結屬性
要宣告可繫結屬性,請執行以下操作:
- 從 BindableBase 類繼承您的 ViewModel;
- 在屬性 getter 和 setter 中使用 GetValue 和 SetValue 方法。
C#
using DevExpress.Mvvm; public class ViewModel : BindableBase { public string FirstName { get { return GetValue<string>(nameof(FirstName)); } set { SetValue(value, nameof(FirstName)); } } }
VB.NET
Imports DevExpress.Mvvm Public Class ViewModel Inherits BindableBase Public Property FirstName() As String Get Return GetValue(Of String)(NameOf(FirstName)) End Get Set(ByVal value As String) SetValue(value, NameOf(FirstName)) End Set End Property End Class
BindableBase 類公開使用 CallerMemberNameAttribute 的 GetValue 和 SetValue 過載,您不必將屬性名稱傳遞給這些方法的引數,這簡化了可繫結屬性宣告:
C#
using DevExpress.Mvvm; public class ViewModel : BindableBase { public string FirstName { get { return GetValue<string>(); } set { SetValue(value); } } }
VB.NET
Imports DevExpress.Mvvm Public Class ViewModel Inherits BindableBase Public Property FirstName() As String Get Return GetValue(Of String)() End Get Set(ByVal value As String) SetValue(value) End Set End Property End Class
注意:CallerMemberNameAttribute 在 .NET Framework 4.5 及更高版本中可用。
屬性值儲存在內部字典中:
- GetValue 方法使用此字典獲取屬性值;
- SetValue 方法使用屬性名稱作為鍵將屬性值儲存在字典中。
SetValue 方法返回指示屬性是否已更改的 True 或 False 值。 如果為屬性設定相同的值,SetValue 方法將返回 False,並且不會發送更改通知。
C#
using DevExpress.Mvvm; public class ViewModel : BindableBase { public string FirstName { get { return GetValue<string>(); } set { if (SetValue(value)) NotifyFullNameChanged(); else MessageBox.Show("Could not change value!"); } } }
VB.NET
Imports DevExpress.Mvvm Public Class ViewModel Inherits BindableBase Public Property FirstName() As String Get Return GetValue(Of String)() End Get Set(ByVal value As String) If Not SetValue(value) Then NotifyFullNameChanged() Else MessageBox.Show("Could not change value!") End If End Set End Property End Class
屬性值更改時執行自定義程式碼
SetValue 方法具有將回調方法作為引數的過載,在更改屬性值後呼叫此回撥。
C#
using DevExpress.Mvvm; public class ViewModel : BindableBase { public string FirstName { get { return GetValue<string>(); } set { SetValue(value, changedCallback: OnFirstNameChanged); } } void OnFirstNameChanged() { //... } }
VB.NET
Imports DevExpress.Mvvm Public Class ViewModel Inherits BindableBase Public Property FirstName() As String Get Return GetValue(Of String)() End Get Set(ByVal value As String) SetValue(value, changedCallback:= AddressOf OnFirstNameChanged) End Set End Property Sub OnFirstNameChanged() '... End Sub End Class
手動引發 INotifyPropertyChanged.PropertyChanged
如果您需要為特定屬性引發 INotifyPropertyChanged.PropertyChanged 事件,請使用 RaisePropertyChanged/RaisePropertiesChanged 方法。
C#
using DevExpress.Mvvm; public class ViewModel : BindableBase { public string FirstName { get { return GetValue<string>(); } set { SetValue(value, changedCallback: NotifyFullNameChanged); } } public string LastName { get { return GetValue<string>(); } set { SetValue(value, changedCallback: NotifyFullNameChanged); } } public string FullName { get { return FirstName + " " + LastName; } } void NotifyFullNameChanged() { RaisePropertyChanged(nameof(FullName)); } }
VB.NET
Imports DevExpress.Mvvm Public Class ViewModel Inherits BindableBase Public Property FirstName() As String Get Return GetValue(Of String)() End Get Set(ByVal value As String) SetValue(value, changedCallback:= AddressOf NotifyFullNameChanged) End Set End Property Public Property LastName() As String Get Return GetValue(Of String)() End Get Set(ByVal value As String) SetValue(value, changedCallback:= AddressOf NotifyFullNameChanged) End Set End Property Public ReadOnly Property FullName() As String Get Return FirstName & " " & LastName End Get End Property Private Sub NotifyFullNameChanged() RaisePropertyChanged(Function() FullName) End Sub End Class
使用帶有支援欄位的屬性
當一個屬性被頻繁訪問或更新時,應用程式的效能可能會降低,因為屬性值儲存在字典中。 要提高應用程式的效能,請將屬性值儲存在支援欄位中。
C#
using DevExpress.Mvvm; public class ViewModel : BindableBase { string _FirstName; public string FirstName { get { return _FirstName; } set { SetValue(ref _FirstName, value, changedCallback: NotifyFullNameChanged); } } } VB.NET Imports DevExpress.Mvvm Public Class ViewModel Inherits BindableBase Private _FirstName As String Public Property FirstName() As String Get Return _FirstName End Get Set(ByVal value As String) SetValue(_FirstName, value, changedCallback:= AddressOf NotifyFullNameChanged) End Set End Property End Class
.NET Framework 4.0 中的 BindableBase
可繫結屬性
使用 GetProperty 和 SetProperty 方法來實現可繫結屬性。
C#
using DevExpress.Mvvm; public class ViewModel : BindableBase { public string FirstName { get { return GetProperty(() => FirstName); } set { SetProperty(() => FirstName, value); } } }
VB.NET
Imports DevExpress.Mvvm Public Class ViewModel Inherits BindableBase Public Property FirstName As String Get Return GetProperty(Function() FirstName) End Get Set(value As String) SetProperty(Function() FirstName, value) End Set End Property End Class
GetProperty 和 SetProperty 方法的第一個引數是一個 lambda 表示式,它返回用於標識目標屬性名稱的屬性。 屬性名稱是使用靜態 BindableBase.GetPropertyName<T> 方法在內部獲取的。
屬性值更改時執行自定義程式碼
SetProperty 方法返回指示屬性是否已更改的 True 或 False 值。如果將該屬性設定為相同的值,SetProperty 方法將返回 False,並且不會發送更改通知。 SetProperty 方法具有將回調方法作為引數的過載,此回撥在欄位更改後呼叫。
C#
using DevExpress.Mvvm; public class ViewModel : BindableBase { public string FirstName { get { return GetProperty(() => FirstName); } set { SetProperty(() => FirstName, value, OnFirstNameChanged); } } void OnFirstNameChanged() { //... } }
VB.NET
Imports DevExpress.Mvvm Public Class ViewModel Inherits BindableBase Public Property FirstName As String Get Return GetProperty(Function() FirstName) End Get Set(value As String) SetProperty(Function() FirstName, value, AddressOf OnFirstNameChanged) End Set End Property Sub OnFirstNameChanged() '... End Sub End Class
手動引發 INotifyPropertyChanged.PropertyChanged
如果您需要為特定屬性引發 INotifyPropertyChanged.PropertyChanged 事件,請使用 RaisePropertyChanged/RaisePropertiesChanged 方法。
C#
using DevExpress.Mvvm; public class ViewModel : BindableBase { public string FullName { get { return string.Format("{0} {1}", FirstName, LastName); } } public string FirstName { get { return GetProperty(() => FirstName); } set { SetProperty(() => FirstName, value, OnFirstNameChanged); } } public string LastName { get { return GetProperty(() => LastName); } set { if(SetProperty(() => LastName, value)) RaisePropertyChanged(() => FullName); } } void OnFirstNameChanged() { RaisePropertyChanged(() => FullName); } }
VB.NET
Imports DevExpress.Mvvm Public Class ViewModel Inherits BindableBase Public ReadOnly Property FullName As String Get Return String.Format("{0} {1}", FirstName, LastName) End Get End Property Public Property FirstName As String Get Return GetProperty(Function() FirstName) End Get Set(value As String) SetProperty(Function() FirstName, value, AddressOf OnFirstNameChanged) End Set End Property Public Property LastName As String Get Return GetProperty(Function() LastName) End Get Set(value As String) If SetProperty(Function() LastName, value) Then RaisePropertyChanged(Function() FullName) End If End Set End Property Sub OnFirstNameChanged() RaisePropertyChanged(Function() FullName) End Sub End Class
使用帶有支援欄位的屬性
當屬性被頻繁更新時(由於從 lambda 表示式計算屬性名稱並將屬性值儲存在字典中),應用程式效能可能會降低。 要適應這些情況,請使用儲存變數來儲存屬性,並使用 BindableBase.GetPropertyName<T> 方法從靜態建構函式計算一次屬性名稱。
C#
using DevExpress.Mvvm; public class ViewModel : BindableBase { static string Property1Name; static ViewModel() { Property1Name = BindableBase.GetPropertyName(() => new ViewModel().Property1); } string property1; public string Property1 { get { return property1; } set { SetProperty(ref property1, value, Property1Name); } } }
VB.NET
Imports DevExpress.Mvvm Public Class ViewModel Inherits BindableBase Shared Property1Name As String Shared Sub New() Property1Name = BindableBase.GetPropertyName(Function() New ViewModel().Property1) End Sub Dim _Property1 As String Public Property Property1 As String Get Return _Property1 End Get Set(value As String) SetProperty(_Property1, value, Property1Name) End Set End Property End Class
DevExpress WPF擁有120+個控制元件和庫,將幫助您交付滿足甚至超出企業需求的高效能業務應用程式。通過DevExpress WPF能建立有著強大互動功能的XAML基礎應用程式,這些應用程式專注於當代客戶的需求和構建未來新一代支援觸控的解決方案。 無論是Office辦公軟體的衍伸產品,還是以資料為中心的商業智慧產品,都能通過DevExpress WPF控制元件來實現。
DevExpress技術交流群6:600715373 歡迎一起進群討論