2016-11-08 104 views
1

我試圖顯示XAML中的項目列表。我從公共API獲取列表,將其轉換爲我需要的類,然後我想顯示它。ObservableCollection不顯示在UI中

public static async Task PopulateListAsync(ObservableCollection<MyClass> myList) { 
    var listContainer = await GetListAsync(); 

    foreach (var item in listContainer) { 
     //converting from one class to another, editing some properties and such 
     myList.Add(item); 
    } 
} 

,並在MainPage.cs我

public ObservableCollection<MyClass> Value { get; set; } 

public MainPage() { 
    this.InitializeComponent(); 
    Value = new ObservableCollection<MyClass>(); 
} 

private async void Page_Loaded(object sender, RoutedEventArgs e) { 
    await PopulateListAsync(Value); 
} 

我顯示在XAML罰款。

但後來我想介紹的過濾。所以我得到的數據,將它們轉換爲一些類並將它們插入到列表中,然後使用LINQ進行過濾(在ObservableCollection中進行過濾似乎更容易)。

基本上我與FormatListAsync()其中,而不是直接插入數據到ObservableCollection<>,返回一個List<>取代PopulateListAsync()。然後,我有一個「中間人」功能

public static async Task PopulateListAsync(ObservableCollection<MyClass> myList) { 
    myList = new ObservableCollection<MyClass>(await FormatListAsync()); 
    //filtering itself isn't implemented yet, but it would be placed here 
} 

我可能只是環槽mylist並添加一個接一個進入ObservableCollection<>,但我覺得肯定有一個更好的方法。

我想我應該實現一些PropertyChanged事件或類似的東西,但我嘗試了幾個(例如this one),但未成功。我不認爲我很理解如何實施它。

+0

我不認爲你可以做Value = new ObservableCollection ();因爲Value屬性是字符串類型。一個錯字可能? –

+0

只是一個錯字。抱歉。 – rancor1223

+0

你是缺少onPropertyChange爲observablecollection – Master

回答

1

如果您分配的方法參數新值,那麼你只需要改變引用的副本收集和不改變源引用。你可以閱讀更多關於passing reference types as method parameters on MSDN

另外,如果你將改變,不是實現INotifyPropertyChanged本身那麼你就必須在UI沒有變化,因爲你的觀點不知道的變化特性。

在你可以操縱源集合,而不是創造新的簡單易行的方式。只是這樣做

public static async Task PopulateListAsync(ObservableCollection<MyClass> myList) 
{ 
    // newList can be an List<MyClass> type, not ObservableCollection 
    var newList = await FormatListAsync(); 

    // change displayed list with new data 
    myList.Clear(); 
    foreach(var newValue in newList) 
     myList.Add(newValue); 
} 

另一種選擇,可以實現INotifyPropertyChanged您的視圖模型和Value setter方法提高PropertyChanged事件:

private ObservableCollection<MyClass> _value; 
public ObservableCollection<MyClass> Value 
{ 
    get 
    { 
     return _value; 
    } 
    set 
    { 
     // I hope this line of code will convince you to give more clear variable name 
     if(value != _value) 
     { 
      _value = value; 
      NotifyPropertyChanged(nameof(Value)); 
     } 
    } 
} 

此外,你需要直接分配ValuePopulateListAsync()

public static async Task PopulateListAsync() 
{ 
    Value = new ObservableCollection<MyClass>(await FormatListAsync()); 
} 
+0

我雖然是第一種做事的方式。我想知道是否有更好的方法。關於'NotifyPropertyChanged' - 我可以在不使用MVVM模式的情況下實現它嗎?這是我在C#中的第一個合適的項目,我真的放棄了MVVM,因爲我無法實現它。 – rancor1223

+0

@ rancor1223好,MVVM是更好的辦法:)另外,你並不需要,如果你正在改變整個列表,那麼你的財產可能有型'名單'使用'ObservableCollection'。如果要動態操作集合(使用清除,添加和其他方法),請使用ObservableCollection。 好的,你可以爲你的對象實現INPC,它不是分離的類,而是你的視圖的數據源。 此外,直接操縱控件及其屬性的方法非常糟糕: 'ObservableCollection data = new ObservableCollection (...); ListBox.ItemsSource = data;' –

+0

下次我會給MVVM一個鏡頭。這對我來說太多了:)。我將會看到僅僅使用一個'List <>',但是我認爲'ObservableCollection <>'給了我一些空間,以便在需要的時候使用它。非常感謝您的幫助! – rancor1223