Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何更新ObservableCollection中的现有项ViewModel,该集合由ObservableCollection填充_C#_System.reactive_Reactive - Fatal编程技术网

C# 如何更新ObservableCollection中的现有项ViewModel,该集合由ObservableCollection填充

C# 如何更新ObservableCollection中的现有项ViewModel,该集合由ObservableCollection填充,c#,system.reactive,reactive,C#,System.reactive,Reactive,有一个ObservableCollection由ObservableCollection填充,我想知道更新集合中的ItemViewModel(如果已经存在)的最有效和最正确的方法是什么。我提出了两个解决方案: 解决方案1 使MainViewModel负责识别该项是否已存在于ObservableCollection中,如果是,则执行更新: MainViewModel.cs private readonly SortedObservableCollection<IConversationPre

有一个ObservableCollection由ObservableCollection填充,我想知道更新集合中的ItemViewModel(如果已经存在)的最有效和最正确的方法是什么。我提出了两个解决方案:

解决方案1

使MainViewModel负责识别该项是否已存在于ObservableCollection中,如果是,则执行更新:

MainViewModel.cs

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
自己

  • 有没有比这些更细粒度的解决方案
  • 在解决方案2中为每个项目
    ViewModel
    创建多个订阅是否会产生性能问题

  • 创建两个订阅将创建两个完整的可观察管道-这可能意味着您原始资源/查询的两倍-无论做什么。如果可观察是热的,则不会。因此,它将只提供新的对话。不,我坚持我的原始评论。无论是热的还是不热的。始终会有两个可观察管道但我确实说过,这可能意味着将原始资源/查询翻倍。热查询将阻止原始资源/查询翻倍,但它不会阻止创建两个完整的可观察管道。问题是,解决方案2的计划不仅仅是创建第二个订阅(因此是第二个管道)但对于每个viewmodel,都要创建一个(如此多的完整管道)。这会造成性能问题吗?您能提供一个示例让我看看吗?