我有测试应用程序,它在循环中向ListBox添加项目。现在,当所有项目都添加到ObservableCollection时,ListBox会更新。我需要在添加每个项目时更新ListBox。请帮助俄罗斯人=)
这是我的代码:
MainWindow.xaml
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="432,288.04,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<ListBox x:Name="urlsListBox" ItemsSource="{Binding Urls}" HorizontalAlignment="Left" Height="300" Margin="10,10,0,0" VerticalAlignment="Top" Width="417"/>
</Grid>
MainWindow.xaml.cs
/// <summary>
/// Логика взаимодействия для MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ViewModel model = new ViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = model;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
model.GetUrls();
}
}
ViewModel.cs
class ViewModel
{
public ObservableCollection<Url> Urls { get; set; }
public ViewModel()
{
Urls = new ObservableCollection<Url>();
}
public void GetUrls()
{
for (int i = 0; i < 5; i++)
{
Urls.Add(new Url { link = i.ToString() });
//Thread.Sleep(300);
}
}
}
public class Url
{
public string link { get; set; }
}
答案 0 :(得分:1)
我认为您需要在每次添加新项目时通知UI有关URL observable集合中发生的更改。
如果您已在视图模型中实现了INotifyPropertyChanged,则注册可观察集合,并在其中发生任何更改。
private ObservableCollection<Url> _urls;
public ObservableCollection<Url> Urls
{ get
{
return _urls;
}
set
{
_urls = value;
OnPropertyModified("Urls");
}
}
答案 1 :(得分:0)
我想要收集UI to update on every item addition
。
查看Thread.Sleep(300)
,我假设您要在将另一个项目添加到集合之前等待300毫秒。
DispatcherTimer
正是您所寻找的。此示例将起作用:
public void GetUrls()
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 0, 0, 300);
int i = 0;
timer.Tick += (s, e) =>
{
Urls.Add(new Url { link = i.ToString() });
++i;
if (i == 5)
timer.Stop();
};
timer.Start();
}
这将在每300毫秒后在集合中添加项目,并在项目计数达到5时停止计时器。
就像我在评论中提到的那样
与UI线程关联的调度程序可以在a处理一个操作 时间。当它将项目添加到集合时,它无法处理渲染 同时操作。因此GUI不会刷新。 DispatcherTimer的使用为渲染操作提供了一些时间来处理。
没有DispatcherTimer
的另一种方法是enqueue empty delegate on UI dispatcher with Render priority
,以便优先处理优先级高于渲染(包括渲染)的所有操作,然后再转移到集合中的另一个项目。
public void GetUrls()
{
for (int i = 0; i < 5; i++)
{
Urls.Add(new Url { link = i.ToString() });
App.Current.Dispatcher.Invoke((Action)(() => { }),
DispatcherPriority.Render);
}
}