Reputation: 273
I have test app which adding items to ListBox in loop. Now, ListBox updates, when all items added to ObservableCollection. I need to update ListBox when every item added. Please, help russian guy =)
Here is my code:
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; }
}
Upvotes: 1
Views: 1337
Reputation: 85
I think you need to notify the UI about the change happening in the URL observable collection each time it adds a new item.
If you have implemented INotifyPropertyChanged in your view model then register the observable collection with any change happening in it.
private ObservableCollection<Url> _urls;
public ObservableCollection<Url> Urls
{ get
{
return _urls;
}
set
{
_urls = value;
OnPropertyModified("Urls");
}
}
Upvotes: 1
Reputation: 81253
You want UI to update on every item addition
in collection i guess.
Looking at Thread.Sleep(300)
, i am assuming you want to wait for 300 milliseconds before adding another item to collection.
DispatcherTimer
is what you are looking for then. This sample will work:
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();
}
This will add item in collection after every 300 ms and will stop timer once item count reaches to 5.
Like i mentioned in comment
Dispatcher associated with UI thread can process one operation at a time. When it's adding item to collection, it can't process Rendering operation at same time. Hence GUI not getting refreshed. Usage of DispatcherTimer gives some time to rendering operations to get processed.
Another approach without DispatcherTimer
would be to enqueue empty delegate on UI dispatcher with Render priority
so that all operations with priority higher than Render (including Render) gets processed before moving to addition of another item in collection.
public void GetUrls()
{
for (int i = 0; i < 5; i++)
{
Urls.Add(new Url { link = i.ToString() });
App.Current.Dispatcher.Invoke((Action)(() => { }),
DispatcherPriority.Render);
}
}
Upvotes: 0