数据和属性绑定
根据您绑定的属性,有三种可能的情况:
常规绑定——ViewModel属性绑定到任何不可编辑的View元素的属性。由于元素不可编辑,因此不需要将更新通知发送回绑定属性(单向绑定)。
数据绑定——Model属性(数据字段)绑定到编辑器属性,如果用户可以更改编辑器值,则需要更新绑定属性(双向绑定)。
属性依赖性——绑定同一个ViewModel的两个属性。
常规绑定
如果需要将数据从一个属性传递到另一个ViewModel的属性,您可以使用标准的数据绑定API,或者推荐使用DevExpress MvvmContext.SetBinding方法。
例如,视图有一个没有文本的,ViewModel有一个可绑定的字符串“LabelText”属性,使用以下任何一种方法将属性值传递给此Label。
C#:
//ViewModel code [POCOViewModel()] public class Form1ViewModel { public Form1ViewModel() { LabelText = "Value stored in ViewModel"; } public virtual string LabelText { get; set; } } //View code //option #1 (recommended): SetBinding method var fluent = mvvmContext1.OfType<Form1ViewModel>(); fluent.SetBinding(labelControl1, l => l.Text, x=>x.LabelText); //option #2: DataBindings Form1ViewModel viewModel = mvvmContext1.GetViewModel<Form1ViewModel>(); labelControl1.DataBindings.Add("Text", viewModel, "LabelText");
VB.NET:
'ViewModel code <POCOViewModel()> Public Class Form1ViewModel Public Sub New() LabelText = "Value stored in ViewModel" End Sub Public Overridable Property LabelText() As String End Class 'View code 'option #1 (recommended): SetBinding method Dim fluent = mvvmContext1.OfType(Of Form1ViewModel)() fluent.SetBinding(labelControl1, Function(l) l.Text, Function(x) x.LabelText) 'option #2: DataBindings Dim viewModel As Form1ViewModel = mvvmContext1.GetViewModel(Of Form1ViewModel)() labelControl1.DataBindings.Add("Text", viewModel, "LabelText")
提示:如果需要将编辑器绑定到属性,并选择特定的更新模式,请使用标准数据绑定而不是SetBinding方法(请参阅数据绑定部分)。
POCO视图模型中的更新通知
如果绑定属性的值可以更改,那么将此更改通知相关属性非常重要,为此向相关属性发送更新通知。如果使用的是POCO ViewModels那么 DevExpress框架可以发送这些通知。
在MVVM应用程序中,每个视图都有一个相关的ViewModel。当使用DevExpress MVVM框架时,您应该为每个视图添加一个MvvmContext组件,并将该组件指向与该视图相关的ViewModel,我们建议在设计时通过组件的智能标签菜单来完成这个操作。
您还可以在代码中使用ViewModelType属性来完成此操作。
C#:
mvvmContext.ViewModelType = typeof(ViewModel);
VB.NET:
mvvmContext.ViewModelType = GetType(ViewModel)
框架将分配给MvvmContext组件的每个ViewModel视为POCO (Plain Old CRL Object) ViewModel,POCO视图模型有许多命名和语法约定,如果您遵循它们,框架就会预测您想要做什么并相应地采取行动。例如,更新通知自动发送到(从)“正确”声明的属性。
创建一个 public virtual auto-implemented属性,来允许框架向该属性发送更新通知,还可以将属性设置器声明为protected。
C#:
public virtual string Name { get; set; } public virtual int ID { get; protected set; }
VB.NET:
Public Overridable Property Name() As String Public Overridable Property ID() As Integer Get Return _privateID End Get Protected Set(ByVal value As Integer) _privateID = value End Set End Property
提示:框架会忽略带有支持字段的属性,为了能够绑定这些属性,可以用DevExpress.Mvvm.DataAnnotations.BindableProperty属性来修饰它们。
C#:
using DevExpress.Mvvm.DataAnnotations; //. . . string name; [BindableProperty] public virtual string Name { get { return name; } set { name = value; } }
VB.NET:
Imports DevExpress.Mvvm.DataAnnotations '. . . Private name_field As String <BindableProperty> Public Overridable Property Name() As String Get Return name_field End Get Set(ByVal value As String) name_field = value End Set End Property
如果希望在每次更新属性时调用特定的方法,请在同一属性中指定该方法的名称。
C#:
[BindableProperty(OnPropertyChangedMethodName= "OnLookUpEdit1ValueChanged")] public virtual string Name { // ... }
VB.NET:
<BindableProperty(OnPropertyChangedMethodName:= "OnLookUpEdit1ValueChanged")> Public Overridable ReadOnly Property Name() As String ' ... End Property
在Bindable Properties演示中,一个Label显示了TextEdit编辑器的值。TextEdit被绑定到自动实现的虚拟Text属性(存储原始编辑器值),Label被绑定到Title(存储格式化的“Text”值)。
由于“Text”属性遵循POCO命名约定,所以TextEdit-to-Text绑定是双向的:当ViewModel属性改变时,编辑器更新其值,当用户修改编辑器文本时,ViewModel属性更新其值。Label-to-Title绑定是单向的,因为“Title”属性没有公共集方法。在这个设置中,我们不需要对“Title”进行双向绑定,因为用户不能更改Label文本。
C#:
//View code var fluent = mvvmContext.OfType<ViewModel>(); fluent.SetBinding(editor, ed => ed.EditValue, x => x.Text); fluent.SetBinding(label, lbl => lbl.Text, x => x.Title); //ViewModel code public class ViewModel { public virtual string Text { get; set; } public string Title { get { if(Text == null) return "Title: (Null)"; if(Text.Length == 0) return "Title: (Empty)"; if(string.IsNullOrWhiteSpace(Text)) return "Title: (Whitespace)"; return "Title: " + Text; } } }
VB.NET:
'View code Dim fluent = mvvmContext.OfType(Of ViewModel)() fluent.SetBinding(editor, Function(ed) ed.EditValue, Function(x) x.Text) fluent.SetBinding(label, Function(lbl) lbl.Text, Function(x) x.Title) 'ViewModel code Public Class ViewModel Public Overridable Property Text() As String Public ReadOnly Property Title() As String Get If Text Is Nothing Then Return "Title: (Null)" End If If Text.Length = 0 Then Return "Title: (Empty)" End If If String.IsNullOrWhiteSpace(Text) Then Return "Title: (Whitespace)" End If Return "Title: " & Text End Get End Property End Class
注意:上面的代码演示了“Title”和“Text”属性之间的区别,但并不完整,demo模块还使用属性依赖来在“Text”发生变化时更新“Title”,运行演示可以查看完整的代码。
绑定嵌套和非poco视图模型的属性
如果您需要绑定一个嵌套的ViewModel属性,使用DevExpress.Mvvm.POCO.ViewModelSource.Create方法来创建这个嵌套ViewModel的实例,您可以通过 parent ViewModel访问它,视图绑定语法使用相同的SetBinding方法。
C#:
//Nested ViewModel public class NestedViewModel { public virtual string Text { get; set; } } //Parent ViewModel public class ViewModelWithChild { public ViewModelWithChild() { Child = ViewModelSource.Create<NestedViewModel>(); } public NestedViewModel Child { get; private set; } } //View code var fluent = mvvmContext.OfType<ViewModelWithChild>(); fluent.SetBinding(editor, ed => ed.EditValue, x => x.Child.Text);
VB.NET:
'Nested ViewModel Public Class NestedViewModel Public Overridable Property Text() As String End Class 'Parent ViewModel Public Class ViewModelWithChild Public Sub New() Child = ViewModelSource.Create(Of NestedViewModel)() End Sub Private privateChild As NestedViewModel Public Property Child() As NestedViewModel Get Return privateChild End Get Private Set(ByVal value As NestedViewModel) privateChild = value End Set End Property End Class 'View code Dim fluent = mvvmContext.OfType(Of ViewModelWithChild)() fluent.SetBinding(editor, Function(ed) ed.EditValue, Function(x) x.Child.Text)
如果不使用POCO模型,则框架不会自动发送更新通知。要在这种情况下发送通知,实现接口或创建-PropertyName-Changed事件,注意不能使用mvvmContext.ViewModelType属性,您应该调用mvvmContext.SetViewModel方法将ViewModel实例传递给组件。
C#:
//ViewModel code public class ObjectWithTextAndTitle { string textCore; public string Text { get { return textCore; } set { if(textCore == value) return; textCore = value; OnTextChanged(); } } protected virtual void OnTextChanged() { RaiseTextChanged(); } protected void RaiseTextChanged() { var handler = TextChanged; if(handler != null) handler(this, EventArgs.Empty); } public event EventHandler TextChanged; } //View code mvvmContext.SetViewModel(typeof(ObjectWithTextAndTitle), viewModelInstance); var fluent = mvvmContext.OfType<ObjectWithTextAndTitle>(); fluent.SetBinding(editor, ed => ed.EditValue, x => x.Text);
VB.NET:
'ViewModel code Public Class ObjectWithTextAndTitle Private textCore As String Public Property Text() As String Get Return textCore End Get Set(ByVal value As String) If textCore = value Then Return End If textCore = value OnTextChanged() End Set End Property Protected Overridable Sub OnTextChanged() RaiseTextChanged() End Sub Protected Sub RaiseTextChanged() Dim handler = TextChangedEvent If handler IsNot Nothing Then handler(Me, EventArgs.Empty) End If End Sub Public Event TextChanged As EventHandler End Class 'View code mvvmContext.SetViewModel(GetType(ObjectWithTextAndTitle), viewModelInstance) Dim fluent = mvvmContext.OfType(Of ObjectWithTextAndTitle)() fluent.SetBinding(editor, Function(ed) ed.EditValue, Function(x) x.Text)
数据绑定
要将编辑器绑定到Model属性,请将 添加到View并使用标准的数据绑定API,可选的参数允许您指定属性是否在编辑器值更改时更新其值,以及(如果是)是应该立即发生还是在验证编辑器时发生。
C#:
editor.DataBindings.Add(...);
VB.NET:
editor.DataBindings.Add(...)
实体属性绑定演示定义了一个自定义Entity类,此类的实例用作数据记录并具有ID和Text字段,两个数据字段都绑定到编辑器,并且BindingSource组件存储活动Entity对象。
C#:
//View mvvmContext.ViewModelType = typeof(ViewModel); var fluentApi = mvvmContext.OfType<ViewModel>(); // Create a BindingSource and populate it with a data object. //When a user modifies this object, the "Update" method is called BindingSource entityBindingSource = new BindingSource(); entityBindingSource.DataSource = typeof(Entity); fluentApi.SetObjectDataSourceBinding(entityBindingSource, x => x.Entity, x => x.Update()); // Data Bindings idEditor.DataBindings.Add( new Binding("EditValue", entityBindingSource, "ID")); textEditor.DataBindings.Add( new Binding("EditValue", entityBindingSource, "Text", true, DataSourceUpdateMode.OnPropertyChanged)); //ViewModel public class ViewModel { //... public virtual Entity Entity { get; set; } //... } //Model public class Entity { public Entity(int id) { this.ID = id; this.Text = "Entity " + id.ToString(); } public int ID { get; private set; } public string Text { get; set; } }
VB.NET:
'View mvvmContext.ViewModelType = GetType(ViewModel) Dim fluentApi = mvvmContext.OfType(Of ViewModel)() ' Create a BindingSource and populate it with a data object. 'When a user modifies this object, the "Update" method is called Dim entityBindingSource As New BindingSource() entityBindingSource.DataSource = GetType(Entity) fluentApi.SetObjectDataSourceBinding(entityBindingSource, Function(x) x.Entity, Function(x) x.Update()) ' Data Bindings idEditor.DataBindings.Add(New Binding("EditValue", entityBindingSource, "ID")) textEditor.DataBindings.Add(New Binding("EditValue", entityBindingSource, "Text", True, DataSourceUpdateMode.OnPropertyChanged)) 'ViewModel Public Class ViewModel '... Public Overridable Property Entity() As Entity '... End Class 'Model Public Class Entity Public Sub New(ByVal id As Integer) Me.ID = id Me.Text = "Entity " & id.ToString() End Sub Private privateID As Integer Public Property ID() As Integer Get Return privateID End Get Private Set(ByVal value As Integer) privateID = value End Set End Property Public Property Text() As String End Class
您也可以使用SetBinding方法。
C#:
fluent.SetBinding(idEditor, l => l.EditValue, x => x.Entity.ID); fluent.SetBinding(textEditor, l => l.EditValue, x => x.Entity.Text);
VB.NET:
fluent.SetBinding(idEditor, Function(te) te.EditValue, Function(dl) dl.Entity.ID) fluent.SetBinding(textEditor, Function(te) te.EditValue, Function(dl) dl.Entity.Text)
但在这种情况下,就失去了设置必需的DataSourceUpdateMode的选项,该选项允许您防止过多的更新通知。
属性依赖性
属性依赖关系是来自同一ViewModel的两个属性之间的关系,当一个属性改变时则另一个属性会更新它的值。
在MVVM Best Practices演示中,多个模块演示了以下设置:
- 将两个 TextEdit 控件绑定到 ViewModel “Operand1”和“Operand 2”属性。
- 当用户更改 TextEdit 值时,操作数属性会刷新其值。
- 当操作数属性更改时,它们会更新数字“结果”属性(依赖项#1)。
- “Result”属性更新字符串“ResultText”属性(依赖项#2)。
对于使用示例UI的每个演示模块,将视图元素绑定到ViewModel属性的代码都是相同的。
C#:
mvvmContext.ViewModelType = typeof(MultViewModel); var fluentAPI = mvvmContext.OfType<MultViewModel>(); fluentAPI.SetBinding(editor1, e => e.EditValue, x => x.Operand1); fluentAPI.SetBinding(editor2, e => e.EditValue, x => x.Operand2); fluentAPI.SetBinding(resultLabel, l => l.Text, x => x.ResultText);
VB.NET:
mvvmContext.ViewModelType = GetType(MultViewModel) Dim fluentAPI = mvvmContext.OfType(Of MultViewModel)() fluentAPI.SetBinding(editor1, Sub(e) e.EditValue, Sub(x) x.Operand1) fluentAPI.SetBinding(editor2, Sub(e) e.EditValue, Sub(x) x.Operand2) fluentAPI.SetBinding(resultLabel, Sub(l) l.Text, Sub(x) x.ResultText)
然而,每个模块中的属性依赖声明都不同。
OnPropertyChanged方法
在 POCO ViewModel 中,您可以声明OnXChanged其中 X 是属性名称的方法,当相关属性的值发生变化时,框架会调用这些方法。
C#:
public class MultViewModel { public virtual int Operand1 { get; set; } public virtual int Operand2 { get; set; } public virtual int Result { get; set; } public virtual string ResultText { get; set; } protected void OnOperand1Changed() { UpdateResult(); } protected void OnOperand2Changed() { UpdateResult(); } protected void OnResultChanged() { UpdateResultText(); } void UpdateResult() { Result = Operand1 * Operand2; } void UpdateResultText() { ResultText = string.Format("The result is: {0:n0}", Result); } }
VB.NET:
Public Class MultViewModel Public Overridable Property Operand1() As Integer Public Overridable Property Operand2() As Integer Public Overridable Property Result() As Integer Public Overridable Property ResultText() As String Protected Sub OnOperand1Changed() UpdateResult() End Sub Protected Sub OnOperand2Changed() UpdateResult() End Sub Protected Sub OnResultChanged() UpdateResultText() End Sub Private Sub UpdateResult() Result = Operand1 * Operand2 End Sub Private Sub UpdateResultText() ResultText = String.Format("The result is: {0:n0}", Result) End Sub End Class
自定义更新方法
如果您的更新方法未调用“On…Changed”,请使用该DevExpress.Mvvm.DataAnnotations.BindableProperty属性告诉框架,当属性值更改时应调用此方法。在下面的代码示例中,DevExpress.Mvvm.POCO.RaisePropertyChanged是一个 DevExpress 扩展方法,它将更新通知发送到依赖属性。
C#:
public class SumViewModel { [BindableProperty(OnPropertyChangedMethodName = "NotifyResultAndResultTextChanged")] public virtual int Operand1 { get; set; } [BindableProperty(OnPropertyChangedMethodName = "NotifyResultAndResultTextChanged")] public virtual int Operand2 { get; set; } public int Result { get { return Operand1 + Operand2; } } public string ResultText { get { return string.Format("The result is: {0:n0}", Result); } } protected void NotifyResultAndResultTextChanged() { this.RaisePropertyChanged(x => x.Result); this.RaisePropertyChanged(x => x.ResultText); } }
VB.NET:
Public Class SumViewModel <BindableProperty(OnPropertyChangedMethodName := "NotifyResultAndResultTextChanged")> Public Overridable Property Operand1() As Integer <BindableProperty(OnPropertyChangedMethodName := "NotifyResultAndResultTextChanged")> Public Overridable Property Operand2() As Integer Public ReadOnly Property Result() As Integer Get Return Operand1 + Operand2 End Get End Property Public ReadOnly Property ResultText() As String Get Return String.Format("The result is: {0:n0}", Result) End Get End Property Protected Sub NotifyResultAndResultTextChanged() Me.RaisePropertyChanged(Function(x) x.Result) Me.RaisePropertyChanged(Function(x) x.ResultText) End Sub End Class
属性依赖
使用 attribute 标记依赖属性DevExpress.Mvvm.DataAnnotations.DependsOnProperties,请注意与前面的示例不同,下面的代码仅使用一个依赖项:“ResultText”依赖于两个“Operand”属性,您无法使用此属性创建链接依赖项。
C#:
public class MultViewModelEx { public virtual int Operand1 { get; set; } public virtual int Operand2 { get; set; } [DependsOnProperties("Operand1", "Operand2")] public string ResultText { get { return string.Format("The result is: {0:n0}", Operand1 * Operand2); } } }
VB.NET:
Public Class MultViewModelEx Public Overridable Property Operand1() As Integer Public Overridable Property Operand2() As Integer <DependsOnProperties("Operand1", "Operand2")> Public ReadOnly Property ResultText() As String Get Return String.Format("The result is: {0:n0}", Operand1 * Operand2) End Get End Property End Class
元数据类
在此方法中,创建自定义更新方法并使用单独的元数据类将属性与这些方法链接起来。如果BindableProperty 属性按名称引用更新方法,则该OnPropertyChangedCall方法使用 lambda 表达式来检索方法。当重命名自定义更新方法时,Metadata 类会显示编译错误。
C#:
//View Model code [System.ComponentModel.DataAnnotations.MetadataType(typeof(Metadata))] public class SumViewModel_MetaPOCO { public virtual int Operand1 { get; set; } public virtual int Operand2 { get; set; } public virtual int Result { get; set; } public string ResultText { get { return string.Format("The result is: {0:n0}", Result); } } protected void NotifyResultAndResultTextChanged() { Result = Operand1 + Operand2; this.RaisePropertyChanged(x => x.Result); this.RaisePropertyChanged(x => x.ResultText); } //Metadata class public class Metadata : IMetadataProvider<SumViewModel_MetaPOCO> { void IMetadataProvider<SumViewModel_MetaPOCO>.BuildMetadata(MetadataBuilder<SumViewModel_MetaPOCO> builder) { builder.Property(x => x.Result) .DoNotMakeBindable(); builder.Property(x => x.Operand1). OnPropertyChangedCall(x => x.NotifyResultAndResultTextChanged()); builder.Property(x => x.Operand2). OnPropertyChangedCall(x => x.NotifyResultAndResultTextChanged()); } } }
VB.NET:
<System.ComponentModel.DataAnnotations.MetadataType(GetType(Metadata))> Public Class SumViewModel_MetaPOCO Public Overridable Property Operand1() As Integer Public Overridable Property Operand2() As Integer Public Overridable Property Result() As Integer Public ReadOnly Property ResultText() As String Get Return String.Format("The result is: {0:n0}", Result) End Get End Property Protected Sub NotifyResultAndResultTextChanged() Result = Operand1 + Operand2 Me.RaisePropertyChanged(Function(x) x.Result) Me.RaisePropertyChanged(Function(x) x.ResultText) End Sub 'Metadata class Public Class Metadata Implements IMetadataProvider(Of SumViewModel_MetaPOCO) Private Sub IMetadataProviderGeneric_BuildMetadata(ByVal builder As MetadataBuilder(Of SumViewModel_MetaPOCO)) Implements IMetadataProvider(Of SumViewModel_MetaPOCO).BuildMetadata builder.Property(Function(x) x.Result).DoNotMakeBindable() builder.Property(Function(x) x.Operand1).OnPropertyChangedCall(Function(x) x.NotifyResultAndResultTextChanged()) builder.Property(Function(x) x.Operand2).OnPropertyChangedCall(Function(x) x.NotifyResultAndResultTextChanged()) End Sub End Class End Class
集合绑定
要使用数据源记录填充多项目控件,请使用方法SetItemsSourceBinding。
C#:
var fluentApi = mvvmContext1.OfType<ViewModelClass>(); fluentApi.SetItemsSourceBinding( Target ItemSelector, SourceSelector, MatchExpression, CreateExpression, DisposeExpression, ChangeExpression );
VB.NET:
Dim fluentApi = mvvmContext1.OfType(Of ViewModelClass)() fluentApi.SetItemsSourceBinding(Target ItemSelector, SourceSelector, MatchExpression, CreateExpression, DisposeExpression, ChangeExpression)
Target——需要填充的目标UI元素。
项目选择器——一个表达式,用于检索应该从数据源填充的UI元素的项目集合。
源选择器——一个表达式,用于定位数据源,其项应用于填充目标。
匹配表达式——将数据源项与目标子项进行比较的表达式。当更改或删除数据源记录时,框架将运行此表达式来确定是否应该更新相应的Target集合项。
创建表达式——当出现新的数据源记录时,用于创建新的Target集合项的表达式。
处理表达式——当Target集合项的相关数据源记录被删除时,该表达式将对其进行处理。
更改表达式——指定当匹配表达式得出的目标集合项与数据源记录不同时,如何更新目标集合项。
在MVVM最佳实践演示中,下面的代码用自定义Entity类的对象填充一个列表框,SetBinding方法将编辑器的SelectedItem属性与检索相应Entity对象的ViewModel SelectedEntity属性绑定在一起。
C#:
//View code mvvmContext.ViewModelType = typeof(ViewModel); var fluentApi = mvvmContext.OfType<ViewModel>(); fluentApi.SetItemsSourceBinding( listBox, lb => lb.Items, x => x.Entities, (item, entity) => object.Equals(item.Value, entity), entity => new ImageListBoxItem(entity), null, (item, entity) => { ((ImageListBoxItem)item).Description = entity.Text; } ); fluentApi.SetBinding(listBox, lb => lb.SelectedValue, x => x.SelectedEntity); //ViewModel code public class ViewModel { public virtual Entity SelectedEntity { get; set; } public virtual ObservableCollection<Entity> Entities { get; set;} protected void OnSelectedEntityChanged() { //"Remove" is a custom ViewModel method that deletes a selected entity this.RaiseCanExecuteChanged(x => x.Remove()); } protected void OnEntitiesChanged() { SelectedEntity = Entities.FirstOrDefault(); } } //Model code public class Entity { public Entity(int id) { this.ID = id; this.Text = "Entity " + id.ToString(); } public int ID { get; private set; } public string Text { get; set; } }
VB.NET:
'View code mvvmContext.ViewModelType = GetType(ViewModel) Dim fluentApi = mvvmContext.OfType(Of ViewModel)() fluentApi.SetItemsSourceBinding( listBox, Function(lb) lb.Items, Function(x) x.Entities, Function(item, entity) Object.Equals(item.Value, entity), Function(entity) New ImageListBoxItem(entity), Nothing, Function(item, entity) CType(item, ImageListBoxItem).Description = entity.Text ) fluentApi.SetBinding(listBox, Function(lb) lb.SelectedValue, Function(x) x.SelectedEntity) 'ViewModel code Public Class ViewModel Public Overridable Property SelectedEntity() As Entity Public Overridable Property Entities() As ObservableCollection(Of Entity) Protected Sub OnSelectedEntityChanged() '"Remove" is a custom ViewModel method that deletes a selected entity Me.RaiseCanExecuteChanged(Function(x) x.Remove()) End Sub Protected Sub OnEntitiesChanged() SelectedEntity = Entities.FirstOrDefault() End Sub End Class 'Model code Public Class Entity Public Sub New(ByVal id As Integer) Me.ID = id Me.Text = "Entity " & id.ToString() End Sub Private privateID As Integer Public Property ID() As Integer Get Return privateID End Get Private Set(ByVal value As Integer) privateID = value End Set End Property Public Property Text() As String End Class
触发器
触发器允许您在 ViewModel 属性更改时修改 UI(视图)。在DevExpress 演示中,一个复选框绑定到 ViewModel“IsActive”属性,当此属性的值更改时,触发器会更改 UI 元素(标签)的背景颜色。
C#:
//ViewModel code public class ViewModel { public virtual bool IsActive { get; set; } } //ViewModel code var fluent = mvvmContext.OfType<ViewModel>(); fluent.SetBinding(checkEdit, c => c.Checked, x => x.IsActive); fluent.SetTrigger(x => x.IsActive, (active) => { if(active) label.Appearance.BackColor = Color.LightPink; else label.Appearance.BackColor = Color.Empty; });
VB.NET:
'ViewModel code Public Class ViewModel Public Overridable Property IsActive() As Boolean End Class 'ViewModel code Private fluent = mvvmContext.OfType(Of ViewModel)() fluent.SetBinding(checkEdit, Function(c) c.Checked, Function(x) x.IsActive) fluent.SetTrigger(Function(x) x.IsActive, Sub(active) If active Then label.Appearance.BackColor = Color.LightPink Else label.Appearance.BackColor = Color.Empty End If End Sub)