C# 如何更新ObservableCollection中的现有项ViewModel,该集合由ObservableCollection填充
有一个ObservableCollection由ObservableCollection填充,我想知道更新集合中的ItemViewModel(如果已经存在)的最有效和最正确的方法是什么。我提出了两个解决方案: 解决方案1 使MainViewModel负责识别该项是否已存在于ObservableCollection中,如果是,则执行更新: MainViewModel.csC# 如何更新ObservableCollection中的现有项ViewModel,该集合由ObservableCollection填充,c#,system.reactive,reactive,C#,System.reactive,Reactive,有一个ObservableCollection由ObservableCollection填充,我想知道更新集合中的ItemViewModel(如果已经存在)的最有效和最正确的方法是什么。我提出了两个解决方案: 解决方案1 使MainViewModel负责识别该项是否已存在于ObservableCollection中,如果是,则执行更新: MainViewModel.cs private readonly SortedObservableCollection<IConversationPre
private readonly SortedObservableCollection<IConversationPreviewViewModel> _conversationPreviews = new SortedObservableCollection<IConversationPreviewViewModel>();
public void SubscribeOnConversations()
{
_observeConversationsUseCase
.Conversations
.ObserveOn(_schedulerProvider.Dispatcher)
.Subscribe(OnNext);
}
private void OnNext(Conversation conversation)
{
var previewViewModel = _conversationPreviews.FirstOrDefault(it => it.ConversationId == conversation.ConversationId);
if (previewViewModel == null)
{
IConversationPreviewViewModel conversationPreview = _conversationPreviewFactory.Create(conversation);
_conversationPreviews.Add(conversationPreview);
}
else
{
previewViewModel.UpdateConversation(conversation);
}
}
private readonly SortedObservableCollection\u conversationPreviews=new SortedObservableCollection();
公开作废SubscribeOnConversations()
{
_观察对话情况
.对话
.ObserveOn(_schedulerProvider.Dispatcher)
.认购(OnNext);
}
私有void OnNext(对话)
{
var previewViewModel=\u conversationPreviews.FirstOrDefault(it=>it.ConversationId==conversation.ConversationId);
如果(previewViewModel==null)
{
IConversationPreviewViewModel conversationPreview=\u conversationPreviewFactory.Create(对话);
_添加(conversationPreview);
}
其他的
{
previewViewModel.UpdateConversation(对话);
}
}
解决方案2
主视图模型只负责添加新项目,但更新是每个项目视图模型本身的责任,将每个项目订阅到可观察项目:
public class Conversation
{
public int Id { get; set; }
public string Name { get; set; }
}
public class ConversationItemViewModel
{
private int Id { get; set; }
public string Text { get; private set; }
public ConversationItemViewModel(Conversation conversation, ObserveConversations observeConversations)
{
Id = conversation.Id;
Text = conversation.Name;
PrintStatus("ctor");
observeConversations.Conversations.Where(it => it.Id == Id).Subscribe(OnNext);
}
private void OnNext(Conversation conversation)
{
Text = conversation.Name;
PrintStatus("OnNext");
}
private void PrintStatus(string from)
{
Console.WriteLine($"Id:{Id} Text:{Text} From: {from}");
}
}
public class ObserveConversations
{
public IConnectableObservable<Conversation> Conversations { get; }
public ObserveConversations()
{
Conversations = ConversationsArriving();
Conversations.Connect();
}
public IConnectableObservable<Conversation> ConversationsArriving()
{
var list = new List<Conversation>() { new Conversation(){Id = 1, Name = "name1"},
new Conversation() {Id = 2, Name = "name2" },
new Conversation() {Id = 3, Name = "name3"},
new Conversation() {Id = 2, Name = "updatedname2"}, // Update this
new Conversation() {Id = 4, Name = "name4"},
new Conversation() {Id = 3, Name = "updatedname3"}, // Update this
};
return list.ToObservable().Delay(TimeSpan.FromSeconds(1)).Publish();
}
}
public class MainViewModel
{
private readonly ObserveConversations _observeConversations;
public MainViewModel(ObserveConversations observeConversations)
{
_observeConversations = observeConversations;
}
private ObservableCollection<ConversationItemViewModel> ConversationItemViewModels { get; } = new ObservableCollection<ConversationItemViewModel>();
public void Start()
{
_observeConversations.Conversations
.Distinct(it => it.Id)
.Subscribe(OnNext);
}
private void OnNext(Conversation conversation)
{
ConversationItemViewModels.Add(new ConversationItemViewModel(conversation, _observeConversations));
}
}
class Program
{
static void Main(string[] args)
{
var observeConversations = new ObserveConversations();
var mainViewModel = new MainViewModel(observeConversations);
mainViewModel.Start();
Console.ReadLine();
}
公共课堂对话
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
公共类ConversationItemViewModel
{
私有int Id{get;set;}
公共字符串文本{get;private set;}
公共会话项视图模型(会话会话、观察会话、观察会话)
{
Id=conversation.Id;
Text=conversation.Name;
打印状态(“ctor”);
observeConversations.Conversations.Where(it=>it.Id==Id).Subscribe(OnNext);
}
私有void OnNext(对话)
{
Text=conversation.Name;
打印状态(“OnNext”);
}
私有void打印状态(来自的字符串)
{
WriteLine($“Id:{Id}Text:{Text}From:{From}”);
}
}
公共类观测会话
{
公共IConnectableObservable对话{get;}
公共观察对话()
{
对话=对话驱动();
Conversations.Connect();
}
公共IConnectableObservable会话驱动()
{
var list=new list(){new Conversation(){Id=1,Name=“name1”},
新建对话(){Id=2,Name=“name2”},
新建对话(){Id=3,Name=“name3”},
new Conversation(){Id=2,Name=“updatedname2”},//更新此
新建对话(){Id=4,Name=“name4”},
new Conversation(){Id=3,Name=“updatedname3”},//更新此
};
return list.ToObservable().Delay(TimeSpan.FromSeconds(1)).Publish();
}
}
公共类主视图模型
{
私有只读ObserveConversations\u ObserveConversations;
public main视图模型(ObserveConversations ObserveConversations)
{
_observeConversations=observeConversations;
}
私有ObservableCollection ConversationItemViewModels{get;}=new ObservableCollection();
公开作废开始()
{
_观察对话
.Distinct(it=>it.Id)
.认购(OnNext);
}
私有void OnNext(对话)
{
添加(新的ConversationItemViewModel(对话,_observeConversations));
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var observeConversations=新的observeConversations();
var mainViewModel=新的mainViewModel(观测转换);
mainViewModel.Start();
Console.ReadLine();
}
就个人而言,我觉得解决方案2更好,因为它将更新的责任委托给了每个ViewModel
自己
ViewModel
创建多个订阅是否会产生性能问题创建两个订阅将创建两个完整的可观察管道-这可能意味着您原始资源/查询的两倍-无论做什么。如果可观察是热的,则不会。因此,它将只提供新的对话。不,我坚持我的原始评论。无论是热的还是不热的。始终会有两个可观察管道但我确实说过,这可能意味着将原始资源/查询翻倍。热查询将阻止原始资源/查询翻倍,但它不会阻止创建两个完整的可观察管道。问题是,解决方案2的计划不仅仅是创建第二个订阅(因此是第二个管道)但对于每个viewmodel,都要创建一个(如此多的完整管道)。这会造成性能问题吗?您能提供一个示例让我看看吗?