ObservableCollection未显示在UI中

时间:2016-11-08 20:52:14

标签: c# wpf xaml

我正在尝试在XAML中显示项目列表。我从公共API获取列表,将其转换为我需要的类,然后我想显示它。

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中过滤)。

基本上我将PopulateListAsync()替换为FormatListAsync(),而不是将数据直接插入ObservableCollection<>,而是返回List<>。然后我有一个“中间人”功能

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),但未成功。我不认为我完全理解如何实现它。

1 个答案:

答案 0 :(得分: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);
}

另一个选项是,您可以为ViewModel实施INotifyPropertyChanged并在Value属性的设置器中引发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));
        } 
    }
}

此外,您需要直接在Value

中指定PopulateListAsync()
public static async Task PopulateListAsync() 
{
    Value = new ObservableCollection<MyClass>(await FormatListAsync());
}