Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.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
在ObservableCollection Ordered-C#UWP中添加项目_C#_Wpf_Win Universal App_Observablecollection - Fatal编程技术网

在ObservableCollection Ordered-C#UWP中添加项目

在ObservableCollection Ordered-C#UWP中添加项目,c#,wpf,win-universal-app,observablecollection,C#,Wpf,Win Universal App,Observablecollection,我有一个问题,这很无聊,我花了很多时间用最好的方法解决我的问题 问题:我有两个可观察到的集合。(OCAux-辅助OC,OCMain-主OC绑定UI) 我有http请求,5个请求。对于请求的每个响应,都将添加到项目OCAux中,然后对项目进行排序。将其添加到订购到我的OCMain的每个项目后,这会自动通知UI(已绑定)。问题是,当添加一个新项目时,这个项目没有被订购,因为I'm order是OCAux的结果,即仅根据请求订购。如果您在将物品添加到OCMain后订购该物品,它会闪烁。 我可以在每次添

我有一个问题,这很无聊,我花了很多时间用最好的方法解决我的问题

问题:我有两个可观察到的集合。(OCAux-辅助OC,OCMain-主OC绑定UI)

我有http请求,5个请求。对于请求的每个响应,都将添加到项目OCAux中,然后对项目进行排序。将其添加到订购到我的OCMain的每个项目后,这会自动通知UI(已绑定)。问题是,当添加一个新项目时,这个项目没有被订购,因为I'm order是OCAux的结果,即仅根据请求订购。如果您在将物品添加到OCMain后订购该物品,它会闪烁。 我可以在每次添加项目时订购OCMain,但会在添加项目时导致UI闪烁

这是通过以下方式规避的,但UI中仍然存在这些“闪烁”:

                    foreach (var item in OCMain)
                    {
                        OCAux.Add(item);
                    }

                    ObservableCollection<Movies> moviesSortedByDatetime= new ObservableCollection<Movies>
                    (OCAux.OrderByDescending(item=> item.DateTime));

                    OCMain.Clear();

                    foreach (var item in moviesSortedByDatetime)
                    {
                        if (!OCMain.Contains(item))
                        { 
                          OCMain.Add(item);
                        }
                    }
foreach(OCMain中的变量项)
{
添加(项目);
}
ObservableCollection moviesSortedByDatetime=新的ObservableCollection
(OCAux.OrderByDescending(item=>item.DateTime));
OCMain.Clear();
foreach(电影SortedByDateTime中的var项目)
{
如果(!OCMain.Contains(项))
{ 
添加(项目);
}
}
有人知道如何将插入项保持在可观察集合的正确位置吗


提前感谢您为每次更改不断更新UI的批插入(除非您需要实时更新)。除非您有充分的理由保留
OCAux
,否则我将使用自定义
IObservableCollection
实现使
OCMain
成为一个有序集合,以在批处理完成后推迟通知。这可以通过两种方式完成:

1) 最简单的方法是添加一个禁用通知的
BeginUpdate()
方法。完成收集作业后,可以使用
EndUpdate()
重新启用通知。继承自
ObservableCollection
的类的概念证明:

对于
Count
属性,只需对
INotifyPropertyChanged
接口引发事件
PropertyChanged
应用相同的逻辑即可

2) 第二个选项稍微复杂一点,但即使您不知道批处理操作何时开始和结束,它也可以工作。首先,让我们假设:如果更新延迟100毫秒,用户不会注意到。在这种情况下,我们可以忽略更改,只发送一个
NotifyCollectionChangedAction.Reset
NotificationDelay
毫秒之后。无论您有多少次更新,在第一次更新后的
NotificationDelay
毫秒后只发送一次更新。概念证明:

protected override OnCollectionChanged(NotifyCollectionChangedEventArgs e) {
    // Another event already queued a delayed notification
    if (_isTimerRunning)
        return;

    // Assuming _timer is a System.Timers.Timer object already configured
    // and OnTimerElapsed method attached to its Elapsed event. Note that
    // you may also use System.Threading.Timer, pick the proper one
    // according to MSDN and your requirements
    _isTimerRunning = true;
    _timer.Start(); 
}

private void OnTimerElapsed(Object source, ElapsedEventArgs e) {
    _isTimerRunning = false;
    _timer.Stop();

    base.OnCollectionChanged(
        new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
同样,您必须为
INotifyPropertyChanged
实现执行类似的操作


请注意,在这两种情况下,我们都会删除一些信息,因为
CollectionChanged
不会触发,例如,使用
NotifyCollectionChangedAction.Add
但仅使用
NotifyCollectionChangedAction.Reset
。无论如何,如果只是为了绑定,那么您更感兴趣的是
INotifyPropertyChanged
通知,这应该不会是一个问题。

对于批量插入,为每次更改不断更新UI可能是(除非您需要实时更新)。除非您有充分的理由保留
OCAux
,否则我将使用自定义
IObservableCollection
实现使
OCMain
成为一个有序集合,以在批处理完成后推迟通知。这可以通过两种方式完成:

1) 最简单的方法是添加一个禁用通知的
BeginUpdate()
方法。完成收集作业后,可以使用
EndUpdate()
重新启用通知。继承自
ObservableCollection
的类的概念证明:

对于
Count
属性,只需对
INotifyPropertyChanged
接口引发事件
PropertyChanged
应用相同的逻辑即可

2) 第二个选项稍微复杂一点,但即使您不知道批处理操作何时开始和结束,它也可以工作。首先,让我们假设:如果更新延迟100毫秒,用户不会注意到。在这种情况下,我们可以忽略更改,只发送一个
NotifyCollectionChangedAction.Reset
NotificationDelay
毫秒之后。无论您有多少次更新,在第一次更新后的
NotificationDelay
毫秒后只发送一次更新。概念证明:

protected override OnCollectionChanged(NotifyCollectionChangedEventArgs e) {
    // Another event already queued a delayed notification
    if (_isTimerRunning)
        return;

    // Assuming _timer is a System.Timers.Timer object already configured
    // and OnTimerElapsed method attached to its Elapsed event. Note that
    // you may also use System.Threading.Timer, pick the proper one
    // according to MSDN and your requirements
    _isTimerRunning = true;
    _timer.Start(); 
}

private void OnTimerElapsed(Object source, ElapsedEventArgs e) {
    _isTimerRunning = false;
    _timer.Stop();

    base.OnCollectionChanged(
        new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
同样,您必须为
INotifyPropertyChanged
实现执行类似的操作


请注意,在这两种情况下,我们都会删除一些信息,因为
CollectionChanged
不会触发,例如,使用
NotifyCollectionChangedAction.Add
但仅使用
NotifyCollectionChangedAction.Reset
。无论如何,如果只是为了绑定,那么您更感兴趣的是
INotifyPropertyChanged
通知,这应该不是问题。

将其添加到OCAux。那就点吧。使用OCAux.indexOf(item)获取添加项的索引。然后将其插入OCMain。插入(索引,项目);这就是你想要的吗?我在CollectionViewSource中进行排序,但我只知道WPF。另一个技巧是返回一个IEnumerable,您可以对该Enumerable进行排序并调用NotifyProperty change,但这并不适用于所有情况。非常确定且ObservableCollection没有插入项。请将其添加到OCAux。那就点吧。使用OCAux.indexOf(item)获取添加项的索引。然后将其插入OCMain。插入(索引,项目);这就是你想要的吗?我在收藏品中做这类工作