在ObservableCollection Ordered-C#UWP中添加项目
我有一个问题,这很无聊,我花了很多时间用最好的方法解决我的问题 问题:我有两个可观察到的集合。(OCAux-辅助OC,OCMain-主OC绑定UI) 我有http请求,5个请求。对于请求的每个响应,都将添加到项目OCAux中,然后对项目进行排序。将其添加到订购到我的OCMain的每个项目后,这会自动通知UI(已绑定)。问题是,当添加一个新项目时,这个项目没有被订购,因为I'm order是OCAux的结果,即仅根据请求订购。如果您在将物品添加到OCMain后订购该物品,它会闪烁。 我可以在每次添加项目时订购OCMain,但会在添加项目时导致UI闪烁 这是通过以下方式规避的,但UI中仍然存在这些“闪烁”:在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后订购该物品,它会闪烁。 我可以在每次添
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。插入(索引,项目);这就是你想要的吗?我在收藏品中做这类工作