C# 使用异步任务通知属性更新

C# 使用异步任务通知属性更新,c#,wpf,asynchronous,task,C#,Wpf,Asynchronous,Task,我有一个包含ListView的视图,我在其中加载了一个ObservableCollection 之后,我将从MySQL数据库中为我的集合中的每个项加载一些外部数据 我希望在异步任务中执行这些操作,以防止ui冻结 对于ListView中不可见的所有项,更新都可以正常工作。因为它们是虚拟化的 当前在ListView上可见的项目未更新。如何通知视图更新项目的属性 注意:Viewmodel通过BaseViewModel实现InotifyProperty更改 public class ProductVie

我有一个包含ListView的视图,我在其中加载了一个ObservableCollection

之后,我将从MySQL数据库中为我的集合中的每个项加载一些外部数据

我希望在异步任务中执行这些操作,以防止ui冻结

对于ListView中不可见的所有项,更新都可以正常工作。因为它们是虚拟化的

当前在ListView上可见的项目未更新。如何通知视图更新项目的属性

注意:Viewmodel通过BaseViewModel实现InotifyProperty更改

public class ProductViewModel : BaseTypes.BaseViewModel
{
    public ProductViewModel()
    {
    }

    public void GetProducts(string filter)
    {
        if (filter.Equals(""))
        {
            return;
        }
        Products.Clear();

        Product product = new Product();
        product.GetProductsByHersteller(filter);
        if (product.productsList != null)
        {
            product.productsList.ToList().ForEach(Products.Add);
        }
        GetRanking();
    }

    private ObservableCollection<Product> _Products = new ObservableCollection<Product>();
    public ObservableCollection<Product> Products { get { return _Products; } private set { _Products = value; } }

    async Task GetRanking()
    {
        await Task.Run(() => GetRank());
    }

    private void GetRank()
    {
        foreach (Product item in Products)
        {
            item.Rank.Get(item.Asin);
            NotifyPropertyChanged(nameof(Products));
        }
    }
}
解决方案:

将INotifyPropertyChanged添加到排名类

ViewModel中现在的代码如下:

public void GetProducts(string filter)
{
    if (filter.Equals(""))
    {
        return;
    }
    Products.Clear();

    Product product = new Product();
    product.GetProductsByHersteller(filter);
    if (product.productsList != null)
    {
        product.productsList.ToList().ForEach(Products.Add);
    }
    GetRanking();
}

private ObservableCollection<Product> _Products = new ObservableCollection<Product>();
public ObservableCollection<Product> Products { get { return _Products; } private set { _Products = value; } }

    async void GetRanking()
    {
        await Task.Run(() => GetRank());
    }

    private void GetRank()
    {
        foreach (Product item in Products)
        {
            item.Rank.Get(item.Asin);
        }
    }
公共产品(字符串过滤器)
{
if(filter.Equals(“”)
{
返回;
}
产品;
产品=新产品();
product.GetProductsByHersteller(过滤器);
if(product.productsList!=null)
{
product.productsList.ToList().ForEach(Products.Add);
}
GetRanking();
}
私有ObservableCollection_Products=新ObservableCollection();
公共可观测集合产品{get{return}Products;}私有集合{u Products=value;}
异步void GetRanking()
{
等待任务。运行(()=>GetRank());
}
私有void GetRank()
{
foreach(产品中的产品项)
{
item.Rank.Get(item.Asin);
}
}
您的产品类应该实现INotifyPropertyChanged


然后无需在GetRank()方法中调用NotifyPropertyChanged。

您现在正在从另一个线程执行
GetRank
,该线程不是UI线程。由于
NotifyPropertyChanged
而导致的UI更新将因此失败。查看
Dispatcher.Invoke()
和/或
Dispatcher.BehinInvoke()
这将允许您更新主线程上的结果。@XAMlMAX尝试了相同的结果。用户界面不存在updated@XAMlMAX好的,BeginInvoke()可以工作,但是ui会冻结,直到工作完成。我们可以看到listview控件的xaml吗?我认为您应该在问题中添加更多信息。您尝试过的dispatcher代码,listview的XAML代码,产品类的代码..天哪,您的答案把我推向了正确的方向。我现在已经在Ranking类中添加了INotifyPropertyChanged,现在UI会一个接一个地更新每个项目。但是我很好奇为什么当我将INotifyPropertyChanged添加到Products类中时,更新不起作用,因为它保存了一个类型Ranking的属性。也许您可以添加产品类的代码来处理添加到问题。
public void GetProducts(string filter)
{
    if (filter.Equals(""))
    {
        return;
    }
    Products.Clear();

    Product product = new Product();
    product.GetProductsByHersteller(filter);
    if (product.productsList != null)
    {
        product.productsList.ToList().ForEach(Products.Add);
    }
    GetRanking();
}

private ObservableCollection<Product> _Products = new ObservableCollection<Product>();
public ObservableCollection<Product> Products { get { return _Products; } private set { _Products = value; } }

    async void GetRanking()
    {
        await Task.Run(() => GetRank());
    }

    private void GetRank()
    {
        foreach (Product item in Products)
        {
            item.Rank.Get(item.Asin);
        }
    }