我有一个类在一个简单的foreach
循环中执行一些操作。
对于每次迭代,我都会向WPF listview
添加一个项目。
我的问题是listview
中的值只有在Foreach
循环结束时才可见。
如何在UI上强制刷新?我必须使用后台工作人员吗?
基本上我的代码是这样的:
foreach ( xxx in yyy )
{
Listview.items.add("bla bla bla"):
; some stuff
; some stuff
}
有关信息,“东西”不长,我想我不需要异步编程....只是一种刷新方式...
现在我要填充一个ObservableCollection,然后将它绑定到listview以解决刷新问题:
public static void myClass()
{
public static ObservableCollection<String> names = new ObservableCollection<String>();
public static void DoMyStuff()
{
names.Add("---- Stuff begin at : " + DateTime.Now + " ---" + Environment.NewLine);
var Sources_URL = myDb.url_source;
foreach (var url in Sources_URL)
{
names.Add("------- Do stuff for : " + url.url_root);
// Some Stuff
}
}
}
这是xaml:
<ListView HorizontalAlignment="Stretch" Margin="10,10,10,10" VerticalAlignment="Stretch" Name="LstViewMain" ItemsSource="{Binding Names}" />
有了这个,问题是一样的,我必须等待DoMyStuff()函数的结束才能看到Listview内容。
答案 0 :(得分:2)
UI未更新的原因是您的foreach循环可能在UI线程上运行,因此阻止UI线程直到操作完成。这也是异步编程建议的原因...
要刷新用户界面,您需要使用Dispatcher
的{{1}}(请参阅here):
UIElement
答案 1 :(得分:2)
问题解决了!非常简单,我使用了这一切,一切都很好:))
Public Void UpdateUI()
{
//Here update your label, button or any string related object.
//Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
}
答案 2 :(得分:1)
没有简单的方法来强制更新foreach循环。您应该学习使用C#的异步编程风格。
也许是这样的。
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await Task.Run(async () =>
{
foreach (var item in new string[] { "asd", "asdfasdf", "asd", "asdfasdf", "asd", "asdfasdf", "asd", "asdfasdf" })
{
//You have to invoke this on the dispatcher, because you are on a different thread right now.
Application.Current.Dispatcher.Invoke(() => listbox.Items.Add(item));
await Task.Delay(1000).ConfigureAwait(false);
}
}).ConfigureAwait(false);
}
答案 3 :(得分:-2)
你可以打开线程来做你的东西,这样每个循环可以更快完成。
foreach ( xxx in yyy )
{
Listview.items.add("bla bla bla");
Task t = Task.Run(() =>
{
; some stuff
; some stuff
});
}