2

我想在雙向綁定一個MvxBindableListView模式下,它在查看更新當我設置它在視圖模型值(通過按鈕的點擊命令)。 目前,它僅在佈局在開始/ tabchange滿載更新...不能在雙向模式綁定MvxBindableListView

視圖模型是:

public List<MyType> TestList 
     { 
      get { return _testList; } 
      set 
      { 
       _testList = value; 
       FirePropertyChanged("TestList"); 
      } 
     } 

查看的.axml是:

<Mvx.MvxBindableListView 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     local:MvxBind="{'ItemsSource':{'Path':'TestList','Mode':'TwoWay'}}" 
     local:MvxItemTemplate="@layout/my_item_layout" /> 

回答

5

數據綁定工作的方式是通過名爲INotifyPropertyChanged的接口

這個接口發生的事情是ViewModel每當屬性發生變化時就發送View消息 - 例如,

FirePropertyChanged("TestList"); 

有了一個列表,如果列表本身的內容本身發生變化,這並不起作用 - 例如,當列表中添加或刪除項目時。


要解決這個問題,.Net Mvvm實現包含另一個接口INotifyCollectionChanged

集合 - 例如列表 - 可以實現INotifyCollectionChanged,以便讓視圖知道集合的內容何時更改。

例如,收集可能含有開火事件提示,如:

  • 一切都變了 - NotifyCollectionChangedAction.Reset
  • 項目已經被添加 - NotifyCollectionChangedAction.Add
  • 項目已被刪除 - NotifyCollectionChangedAction.Remove
  • ...

有的簡單介紹了這個接口約12:30到MvvmCross Xaminar http://www.youtube.com/watch?v=jdiu_dH3z5k

Xaminar


要使用此接口用於在小內存中的列表 - 例如少於1000個「小」對象 - 您只需將List<T>更改爲ObservableCollection<T> - ObservableCollection是來自核心.Net庫(來自Microsoft或Mono)的類,它會在添加/刪除程序時觸發正確的事件,刪除列表項目。

您可以在以下位置看到Mono ObservableCollection實現的源代碼:https://github.com/mosa/Mono-Class-Libraries/blob/master/mcs/class/System/System.Collections.ObjectModel/ObservableCollection.cs - 查看此實現值得花點時間,以便您更好地瞭解Mvvm如何與INotifyCollectionChanged配合使用。

如果您使用的ObservableCollection類,那麼你的代碼將變爲:

private ObservableCollection<MyType> _testList; 
    public ObservableCollection<MyType> TestList 
    { 
     get { return _testList; } 
     set 
     { 
      _testList = value; 
      FirePropertyChanged("TestList"); 
      // in vNext use RaisePropertyChanged(() => TestList); 
     } 
    } 

有:

<Mvx.MvxBindableListView 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    local:MvxBind="{'ItemsSource':{'Path':'TestList'}}" 
    local:MvxItemTemplate="@layout/my_item_layout" /> 

注:

  • 結合是OneWay - 這意味着,綁定仍然只是從ViewModel到視圖 - 有沒有更新從View到ViewModel。
  • ObservableCollection被設計爲單線程 - 因此確保集合的所有更改都在UI線程上完成 - 而不是在工作線程上完成。如果您需要,您可以使用ViewModel中的InvokeOnMainThread(() => { /* do work here */ })編組回到UI線程。
  • 在Android中,方式列表的工作方式(通過基礎AdapterView)意味着每當您調用ObservableCollection上的任何更新時,UI列表都會忽略操作提示(添加,刪除等) - 它會對待每個更改作爲一個重置,這將導致整個列表重繪。

對於較大的集合 - 在你不希望所有的內存在同一時間的項目 - 你可能需要自己實現一些數據存儲支持列表。

有一個簡單的SQLite數據支持存儲在https://github.com/slodge/MvvmCross/blob/vnext/Sample%20-%20SimpleDialogBinding/SimpleDroidSql.Core/DatabaseBackedObservableCollection.cs

一個簡單的例子收集數據的這種虛擬化是在WP和WPF應用程序共同 - 例如查看問題和解答,如Is listbox virtualized by default in WP7 Mango?

+0

看起來所提到的視頻已經移到了[這裏](https://www.youtube.com/watch?v=-Ghb3sXe9Ks)。 –

0

我們剛剛發現了一個適用於我們的解決方法!

注意:添加和從列表中刪除更新與新/刪除項目的視圖。但是,沒有反映出現有項目狀態的任何變化。

解決方案:我們清除了我們的列表,並將項目重新添加到具有更新狀態的ViewModel屬性中。調用raisepropertychanged然後模仿雙向綁定行爲。基本上它是刪除所有值並重新添加所有值。