当ObservableCollection项改变时如何更新ListBox?

时间:2013-12-15 14:34:32

标签: c# wpf xaml listbox

我有测试应用程序,它在循环中向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; }
}

2 个答案:

答案 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);
    }
}