2017-09-17 6 views
1

SQLiteの代わりにRealmデータベースを使用するように私のアプリケーションを移植しました。しかし、MVVMと組み合わせてIRealmCollectionの問題が発生しています。レルムでアイテム固有のViewModelを使用する最良の方法は何ですか?

のは、次のモデルを想像してみましょう:私のMainViewModel上の現在のアプローチはこの1つである

public class Item : RealmObject 
{ 
    public string Id { get; } 
} 

を:

public class MainViewModel 
{ 
    public IRealmCollection<Item> { get; private set; } 
} 

私が今直面してる問題はItemがあり、特定のコマンドを持っているということですItemViewModelIRealmCollectionの機能を維持しながら、これらを使用したいと思います。

ItemViewModel

public class ItemViewModel 
{ 
    public Item Model { get; private set; } 
    public ICommand MyCommand { get; private set; } 
} 

私が考えてきたが、私はそれをより簡単な解決策があるかどう不思議に思っていました、いくつかの方法があります。

  • は、そのカスタムObservableCollectionを作成しますが、レルムにサブスクライブする
  • LINQ .Select()拡張機能を使用して、リストのViewModelを作成します。
  • SaレルムでItemViewModel VEの各追加のプロパティまたはコマンド
  • [Ignored]属性を追加します(ItemHelperのような)別のクラスにItemViewModelの外にロジックを移動して、何MainViewModel

からそれを呼び出しますMVVMに似た方法でこの問題を解決するのがベストでしょうか?

答えて

1

コマンドと追加のプロパティが単純で永続化されたItemに埋め込むことができる場合は、その解決策を検討します。これは、RealmObjectsがコレクション内のインデックスにアクセスすると動的に作成されるなど、常に機能するとは限りません。例えば:

var collection = realm.All<Item>(); 
var a = collection.ElementAt(0); 
var b = collection.ElementAt(0); 

あなたabのための別のインスタンスを取得します。つまり、RealmObjectの継承者で非永続状態に頼ることはできません。

public interface IViewModel<T> where T : RealmObject 
{ 
    T Item { get; set; } 
} 

public class MyObservableCollection<TViewModel, TRealmObject> : IReadOnlyList<TViewModel>, INotifyCollectionChanged 
    where TRealmObject : RealmObject 
    where TViewModel : IViewModel<TRealmObject>, new() 
{ 
    private readonly IRealmCollection<TRealmObject> _collection; 

    public TViewModel this[int index] => Project(_collection[index]); 

    private event PropertyChangedEventHandler _propertyChanged; 
    public event NotifyCollectionChangedEventHandler CollectionChanged 
    { 
     add 
     { 
      UpdateCollectionChangedSubscriptionIfNecessary(isSubscribed: true); 
      _collectionChanged += value; 
     } 
     remove 
     { 
      _collectionChanged -= value; 

      UpdateCollectionChangedSubscriptionIfNecessary(isSubscribed: false); 
     } 
    } 

    public MyObservableCollection(IRealmCollection<TRealmObject> collection) 
    { 
     _collection = collection; 
    } 

    private TViewModel Project(TRealmObject obj) 
    { 
     return new TViewModel 
     { 
      Item = obj 
     }; 
    } 

    private void UpdateCollectionChangedSubscriptionIfNecessary(bool isSubscribed) 
    { 
     if (_collectionChanged == null) 
     { 
      if (isSubscribed) 
      { 
       // Subscribe via _collection 
      } 
      else 
      { 
       // Unsubscribe via _collection 
      } 
     } 
    } 
} 
:これがdealbreakerであれば、私はその後RealmObjectを公開するために組成物を使用することができ、あなたのViewModelに突起を IRealmCollectionやお得な情報をラップするカスタムのObservableCollectionを示唆しています
関連する問題