• <menu id="w2i4a"></menu>
  • logo DevExpress WinForm中文手冊

    文檔首頁>>DevExpress WinForm中文手冊>>數(shù)據(jù)和屬性綁定

    數(shù)據(jù)和屬性綁定


    立即下載DevExpress WinForms

    根據(jù)您綁定的屬性,有三種可能的情況:

    常規(guī)綁定——ViewModel屬性綁定到任何不可編輯的View元素的屬性。由于元素不可編輯,因此不需要將更新通知發(fā)送回綁定屬性(單向綁定)。

    數(shù)據(jù)綁定——Model屬性(數(shù)據(jù)字段)綁定到編輯器屬性,如果用戶可以更改編輯器值,則需要更新綁定屬性(雙向綁定)。

    屬性依賴性——綁定同一個ViewModel的兩個屬性。

    常規(guī)綁定

    如果需要將數(shù)據(jù)從一個屬性傳遞到另一個ViewModel的屬性,您可以使用標準的數(shù)據(jù)綁定API,或者推薦使用DevExpress MvvmContext.SetBinding方法。

    例如,視圖有一個沒有文本的LabelControl,ViewModel有一個可綁定的字符串“LabelText”屬性,使用以下任何一種方法將屬性值傳遞給此Label。

    form

    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")

    提示:如果需要將編輯器綁定到屬性,并選擇特定的更新模式,請使用標準數(shù)據(jù)綁定而不是SetBinding方法(請參閱數(shù)據(jù)綁定部分)。

    POCO視圖模型中的更新通知

    如果綁定屬性的值可以更改,那么將此更改通知相關(guān)屬性非常重要,為此向相關(guān)屬性發(fā)送更新通知。如果使用的是POCO ViewModels那么 DevExpress框架可以發(fā)送這些通知。

    在MVVM應(yīng)用程序中,每個視圖都有一個相關(guān)的ViewModel。當使用DevExpress MVVM框架時,您應(yīng)該為每個視圖添加一個MvvmContext組件,并將該組件指向與該視圖相關(guān)的ViewModel,我們建議在設(shè)計時通過組件的智能標簽菜單來完成這個操作。

    mvvm


    您還可以在代碼中使用ViewModelType屬性來完成此操作。

    C#:

    mvvmContext.ViewModelType = typeof(ViewModel);

    VB.NET:

    mvvmContext.ViewModelType = GetType(ViewModel)

    框架將分配給MvvmContext組件的每個ViewModel視為POCO (Plain Old CRL Object) ViewModel,POCO視圖模型有許多命名和語法約定,如果您遵循它們,框架就會預(yù)測您想要做什么并相應(yīng)地采取行動。例如,更新通知自動發(fā)送到(從)“正確”聲明的屬性。

    創(chuàng)建一個 public virtual auto-implemented屬性,來允許框架向該屬性發(fā)送更新通知,還可以將屬性設(shè)置器聲明為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

    如果希望在每次更新屬性時調(diào)用特定的方法,請在同一屬性中指定該方法的名稱。

    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被綁定到自動實現(xiàn)的虛擬Text屬性(存儲原始編輯器值),Label被綁定到Title(存儲格式化的“Text”值)。

    由于“Text”屬性遵循POCO命名約定,所以TextEdit-to-Text綁定是雙向的:當ViewModel屬性改變時,編輯器更新其值,當用戶修改編輯器文本時,ViewModel屬性更新其值。Label-to-Title綁定是單向的,因為“Title”屬性沒有公共集方法。在這個設(shè)置中,我們不需要對“Title”進行雙向綁定,因為用戶不能更改Label文本。

    DevExpress VCL圖表控件

    運行演示

    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”屬性之間的區(qū)別,但并不完整,demo模塊還使用屬性依賴來在“Text”發(fā)生變化時更新“Title”,運行演示可以查看完整的代碼。

    綁定嵌套和非poco視圖模型的屬性

    如果您需要綁定一個嵌套的ViewModel屬性,使用DevExpress.Mvvm.POCO.ViewModelSource.Create方法來創(chuàng)建這個嵌套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模型,則框架不會自動發(fā)送更新通知。要在這種情況下發(fā)送通知,實現(xiàn)INotifyPropertyChanged 接口或創(chuàng)建-PropertyName-Changed事件,注意不能使用mvvmContext.ViewModelType屬性,您應(yīng)該調(diào)用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)

    數(shù)據(jù)綁定

    要將編輯器綁定到Model屬性,請將 BindingSource 添加到View并使用標準的數(shù)據(jù)綁定API,可選的updatemode參數(shù)允許您指定屬性是否在編輯器值更改時更新其值,以及(如果是)是應(yīng)該立即發(fā)生還是在驗證編輯器時發(fā)生。

    C#:

    editor.DataBindings.Add(...);

    VB.NET:

    editor.DataBindings.Add(...)

    實體屬性綁定演示定義了一個自定義Entity類,此類的實例用作數(shù)據(jù)記錄并具有ID和Text字段,兩個數(shù)據(jù)字段都綁定到編輯器,并且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)

    但在這種情況下,就失去了設(shè)置必需的DataSourceUpdateMode的選項,該選項允許您防止過多的更新通知。

    屬性依賴性

    屬性依賴關(guān)系是來自同一ViewModel的兩個屬性之間的關(guān)系,當一個屬性改變時則另一個屬性會更新它的值。

    在MVVM Best Practices演示中,多個模塊演示了以下設(shè)置:

    1. 將兩個 TextEdit 控件綁定到 ViewModel “Operand1”和“Operand 2”屬性。
    2. 當用戶更改 TextEdit 值時,操作數(shù)屬性會刷新其值。
    3. 當操作數(shù)屬性更改時,它們會更新數(shù)字“結(jié)果”屬性(依賴項#1)。
    4. “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 是屬性名稱的方法,當相關(guān)屬性的值發(fā)生變化時,框架會調(diào)用這些方法。

    運行演示

    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
    自定義更新方法

    如果您的更新方法未調(diào)用“On…Changed”,請使用該DevExpress.Mvvm.DataAnnotations.BindableProperty屬性告訴框架,當屬性值更改時應(yīng)調(diào)用此方法。在下面的代碼示例中,DevExpress.Mvvm.POCO.RaisePropertyChanged是一個 DevExpress 擴展方法,它將更新通知發(fā)送到依賴屬性。

    運行演示

    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”屬性,您無法使用此屬性創(chuàng)建鏈接依賴項。

    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

    元數(shù)據(jù)類

    在此方法中,創(chuàng)建自定義更新方法并使用單獨的元數(shù)據(jù)類將屬性與這些方法鏈接起來。如果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

    集合綁定

    要使用數(shù)據(jù)源記錄填充多項目控件,請使用方法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元素。

    項目選擇器——一個表達式,用于檢索應(yīng)該從數(shù)據(jù)源填充的UI元素的項目集合。

    源選擇器——一個表達式,用于定位數(shù)據(jù)源,其項應(yīng)用于填充目標。

    匹配表達式——將數(shù)據(jù)源項與目標子項進行比較的表達式。當更改或刪除數(shù)據(jù)源記錄時,框架將運行此表達式來確定是否應(yīng)該更新相應(yīng)的Target集合項。

    創(chuàng)建表達式——當出現(xiàn)新的數(shù)據(jù)源記錄時,用于創(chuàng)建新的Target集合項的表達式。

    處理表達式——當Target集合項的相關(guān)數(shù)據(jù)源記錄被刪除時,該表達式將對其進行處理。

    更改表達式——指定當匹配表達式得出的目標集合項與數(shù)據(jù)源記錄不同時,如何更新目標集合項。

    MVVM最佳實踐演示中,下面的代碼用自定義Entity類的對象填充一個列表框,SetBinding方法將編輯器的SelectedItem屬性與檢索相應(yīng)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

    觸發(fā)器

    觸發(fā)器允許您在 ViewModel 屬性更改時修改 UI(視圖)。在DevExpress 演示中,一個復(fù)選框綁定到 ViewModel“IsActive”屬性,當此屬性的值更改時,觸發(fā)器會更改 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)
    掃碼咨詢


    添加微信 立即咨詢

    電話咨詢

    客服熱線
    023-68661681

    TOP
    三级成人熟女影院,欧美午夜成人精品视频,亚洲国产成人乱色在线观看,色中色成人论坛 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();