我已经将我的应用移植为使用 Realm 数据库而不是 SQLite。但是,我在 IRealmCollection
与 MVVM 结合时遇到问题。
让我们想象以下模型:
public class Item : RealmObject
{
public string Id { get; }
}
我的 MainViewModel
目前的方法是这样的:
public class MainViewModel
{
public IRealmCollection<Item> { get; private set; }
}
我现在面临的问题是 Item
有特定的命令,位于 ItemViewModel
中。我想在保留 IRealmCollection
特性的同时使用它们。
ItemViewModel
:
public class ItemViewModel
{
public Item Model { get; private set; }
public ICommand MyCommand { get; private set; }
}
我一直在考虑几种方法,但我想知道是否有更简单的解决方案:
- 创建一个订阅 Realm 的自定义
ObservableCollection
- 使用 LINQ
.Select()
扩展从列表中创建一个 ViewModel - 在 Realm 中保存
ItemViewModel
并将[Ignored]
属性添加到每个附加属性或命令 - 将逻辑从
ItemViewModel
移到一个单独的类(如ItemHelper
)并从MainViewModel
调用它
解决此问题的最佳且可能最类似于 MVVM 的方法是什么?
最佳答案
如果您的命令和附加属性很简单并且可以嵌入到持久化的 Item
中,我会采用该解决方案。这可能并不总是有效,例如,因为 RealmObjects 是在访问集合中的索引时动态创建的。例如:
var collection = realm.All<Item>();
var a = collection.ElementAt(0);
var b = collection.ElementAt(0);
将为您提供 a
和 b
的不同实例。这意味着您不能依赖 RealmObject 继承者中的非持久化状态。如果这是一个破坏者,那么我会建议一个自定义的 ObservableCollection,它包装 IRealmCollection
并处理对您的 ViewModel 的投影,然后可以使用组合来公开 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
}
}
}
}
关于c# - 在 Realm 中使用特定于项目的 ViewModel 的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46267688/