C# UI在更新ObservableCollection时冻结
我知道,关于这个话题已经有很多帖子了,但是到目前为止我还没有找到解决这个问题的方法 首先,这是我的C# UI在更新ObservableCollection时冻结,c#,wpf,mvvm,C#,Wpf,Mvvm,我知道,关于这个话题已经有很多帖子了,但是到目前为止我还没有找到解决这个问题的方法 首先,这是我的ItemsControl: <ScrollViewer Style="{StaticResource ScrollViewer}" VerticalScrollBarVisibility="Visible" MaxHeight="475"> <ItemsControl ItemsSource="{Binding CurrentSelectedItems}" Margin="0 1
ItemsControl
:
<ScrollViewer Style="{StaticResource ScrollViewer}" VerticalScrollBarVisibility="Visible" MaxHeight="475">
<ItemsControl ItemsSource="{Binding CurrentSelectedItems}" Margin="0 10 0 0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:ItemControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
为了简单起见,ItemsControl
的ItemsSource
属性绑定到类型为ItemViewModel
的observeCollection
ItemViewModel
包含大约25个属性和一些Prism DelegateCommands
ItemsControl
顶部还有一些按钮,用于更改CurrentSelectedItems
的内容。由于这些项目有时总计多达300个,因此更新UI需要一些时间。在这种情况下,应用程序被冻结了
有没有办法不冻结UI,例如显示微调器/加载消息
提前谢谢
编辑:
控件:ItemControl
是一个简单的自定义控件,包含大约5个标签
和3个相当小的图像
获取WPF工具包并使用BusyIndicator。这将在控件顶部弹出一个窗口,其中有一个移动忙碌指示器。您还可以提供自定义消息 您可以使用任务更新UI,但它需要一个参数列表。为此:
// create an async method
private async void PopulateItems() {
// use task to populate the items
await Task.Run(() => {
for (var item in CurrentSelectedItems) {
this.Dispatcher.Invoke(() => yourItemCollectionControl.Add(item));
}
});
}
尽管有其他答案,但这是无法避免的 WPF是一个SPA(单线程单元),意味着任何UI对象都必须由UI线程创建和拥有。当您有很多UI元素要构建和呈现时,UI线程将非常繁忙 显示UI加载动画的解决方案也不正确,因为此动画也将位于UI线程上,该线程已经在忙于创建和渲染UI集合 只需确保任何处理都在后台线程上,并让UI自行管理即可