2012-03-30 124 views
0

當進度發生變化時,我需要更新下載列表。當已更新綁定列表的現有項目時如何更新ListView

XAML:

class MainWindowViewModel : ViewModelBase 
{ 
    private readonly Logic _logic; 
    public List<Model> UiList { get; set; }   

    public MainWindowViewModel() 
    { 
     _logic = new Logic(); 
     _logic.Update += LogicUpdate; 
     Start = new RelayCommand(() => 
            { 
             var worker = new BackgroundWorker(); 
             worker.DoWork += (sender, args) => _logic.Start(); 
             worker.RunWorkerAsync(); 
            }); 
    } 

    void LogicUpdate(object sender, EventArgs e) 
    { 
     UiList = _logic.List; 
     RaisePropertyChanged("UiList");    
    } 

    public ICommand Start { get; set; } 
} 

邏輯::

public class Logic 
{ 
    readonly List<Model> _list = new List<Model>(); 
    public event EventHandler Update; 

    public List<Model> List 
    { 
     get { return _list; } 
    } 

    public void Start() 
    { 
     for (int i = 0; i < 100; i++) 
     { 
      _list.Clear(); 
      _list.Add(new Model{Progress = i, Title = "title1"}); 
      _list.Add(new Model { Progress = i, Title = "title2" }); 

      var time = DateTime.Now.AddSeconds(2); 
      while (time > DateTime.Now) 
      { } 

      Update(this, EventArgs.Empty); 
     } 
    } 
} 

上面的代碼將不更新創建邏輯類的一個實例,並更新的ListView的內容

<ListView ItemsSource="{Binding UiList}" x:Name="MyListView"> 
    <ListView.View> 
    <GridView> 
     <GridViewColumn Header="Title"/> 
     <GridViewColumn Header="Progress"/> 
    </GridView> 
    </ListView.View> 
</ListView> 

視圖模型UI。我知道雙向如何解決這一問題:

  1. 在XAML代碼隱藏來電:Application.Current.Dispatcher.Invoke(new Action(() => MyListView.Items.Refresh()));

  2. 在視圖模型變化List<>ICollectionView和使用Application.Current.Dispatcher.Invoke(new Action(() => UiList.Refresh()));名單已更新後。

兩種方式導致此問題:ListView控件閃爍彈出,應該是對用戶需求的開放始終關閉後每個 「刷新」

Popup

<Popup Name="Menu" StaysOpen="False"> 

我可以用另一個控件或面板替換彈出窗口,但我需要它的可能性超出主窗口的邊框(如在屏幕上)。但我相信WPF有另一種方式來更新ListView的內容(不閃爍)。

PS:對不起,長期的問題,但我不知道如何更簡單地形容了......

+0

您應該將列表更改爲ObservableCollection。 – Silvermind 2012-03-30 16:23:31

回答

0

我已經找到了答案在這裏:How do I update an existing element of an ObservableCollection?

的ObservableCollection是部分解決方案。 ObservableCollection僅在集合更改(項目添加,刪除等等)時才上升CollectionChanged事件。爲了支持現有項目的更新,集合中的每個對象(在我的情況下爲Model類)必須實現INotifyPropertyChanged接口。

// I used this parent (ViewModelBase) for quick testing because it implements INotifyPropertyChanged 
public class Model : ViewModelBase 
{ 
    private int _progress; 
    public int Progress 
    { 
     get { return _progress; } 
     set 
     { 
      _progress = value; 
      RaisePropertyChanged("Progress"); 
     } 
    } 

    public string Title { get; set; } 
} 
1

認爲的原因,這行不工作:

RaisePropertyChanged("UiList"); 

是因爲你並沒有真正改變名單。你清除它並重新填充它,但它仍然是對同一列表的引用。我很想看看會發生什麼情況,而不是清理清單並重新填充,而是實際創建了一個新清單。我認爲應該更新您的ListView如您所料。無論它是否對彈出窗口有影響,我都不知道。

+0

是的,創建一個新的列表給了我一個新的方法(最好btw,謝謝!)來修復listview更新。但它不能解決彈出問題... – 2012-03-30 14:42:55

相關問題