Wpf 更新到列表框绑定集合后刷新UI

Wpf 更新到列表框绑定集合后刷新UI,wpf,mvvm,listbox,observablecollection,Wpf,Mvvm,Listbox,Observablecollection,我试图用WPF/MVVM直观地显示一个项目(在我的例子中是一个位图图像)已添加到列表框中的集合中。为了提供一些背景,我用一个捕获卡捕获流式视频,并在视频流式传输时拍摄静止图像。通过单击UI上的“静止图像”按钮可以捕获这些图像。在拍摄完一幅图像后,我想在UI上的一个单独的面板中显示一幅所述图像的缩略图。我知道需要做什么才能做到这一点,但我似乎无法让它发挥作用。现在,我的模型进行所有的数据检索 public ObservableCollection<BitmapImage> GetAss

我试图用WPF/MVVM直观地显示一个项目(在我的例子中是一个位图图像)已添加到列表框中的集合中。为了提供一些背景,我用一个捕获卡捕获流式视频,并在视频流式传输时拍摄静止图像。通过单击UI上的“静止图像”按钮可以捕获这些图像。在拍摄完一幅图像后,我想在UI上的一个单独的面板中显示一幅所述图像的缩略图。我知道需要做什么才能做到这一点,但我似乎无法让它发挥作用。现在,我的模型进行所有的数据检索

public ObservableCollection<BitmapImage> GetAssetThumbnails()
{
    var imageDir = ImgPath != null ? new DirectoryInfo(ImgPath) : null;
    if(imageDir != null)
    {
        try
        {
            foreach (FileInfo imageFile in imageDir.GetFiles("*.jpg"))
            {
                var uri = new Uri(imageFile.FullName);
                _assetThumbnails.Add(new BitmapImage(uri));
            }

        }
        catch (Exception)
        {
            return null;
        }
    }

    return _assetThumbnails;
}
然后,在我的XAML文件中,我将ListBox的项源绑定到AssetCollection

<ListBox x:Name="lstBoxAssets" ItemsSource="{Binding AssetCollection}" Grid.Row="1" Background="{DynamicResource GrayColor}" Margin="5,0,0,5" ></ListBox>   


我已经读到集合中的每个项都应该实现INotifyPropertyChanged接口。我尝试为实现该功能的位图图像创建一个包装器类,但它也不起作用。这里有我遗漏的东西吗?图像最初会显示,但在捕获并保存图像后不会刷新。我有一种感觉,这是由没有被调用的事件
PropertyChanged
引起的。通过调试,我注意到当它被选中时总是空的,因此从来没有调用
onpropertychanged
方法。不过,我不确定应该在哪里添加此事件处理程序。我只使用代码隐藏文件将视图模型的数据上下文添加到视图中,仅此而已。这是我通常认为添加任何事件处理的地方。有人能看到我这里缺少的简单内容吗?

您是在更新列表时更改
可观察集合
,还是更改集合中存储的项目

如果要更改集合中的项,则需要找到一种方法,在单个项更改时告诉WPF集合已更改,以便WPF知道如何重新绘制它

通常集合中的项实现了
INotifyPropertyChanged
,因此很容易将
PropertyChange
通知附加到列表中的项,通知WPF在属性更改时引发
CollectionChanged
事件

// Wireup CollectionChanged in Constructor
public MyViewModel()
{
    ListOfSomeItems = new List<SomeItem>();
    AssetCollection.CollectionChanged += AssetCollection_CollectionChanged;
}

// In CollectionChanged event, wire up PropertyChanged event on items
void AssetCollection_CollectionChanged(object sender, CollectionChangedEventArgs e)
{
    if (e.NewItems != null)
    {
        foreach(Asset item in e.NewItems)
            item.PropertyChanged += Asset_PropertyChanged;
    }
    if (e.OldItems != null)
    {
        foreach(Asset item in e.OldItems)
            item.PropertyChanged -= Asset_PropertyChanged;
    }
}

// In PropertyChanged, raise CollectionChanged event
void Asset_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    OnPropertyChanged("AssetCollection");
}
如果您通过添加/删除项来更改
ObservableCollection
本身,并且没有看到UI更新,那么听起来可能是我们看不到的某个地方的语法错误

我看到的最常见的变化是对私有财产而不是公共财产进行更改

// Will not raise the CollectionChanged notification
_assetCollection = _assetModel.GetAssetThumbnails();

// Will raise the CollectionChanged notification
AssetCollection = _assetModel.GetAssetThumbnails();

尽管我也看到很多人使用
列表
或自定义集合而不是
可观察集合
,这不会引发
集合更改
事件。

Try“我尝试为实现该功能的位图图像创建包装类,但也没有成功。”。对项目的更改需要通过NotifyPropertyChanged来自项目。你使用公共财产了吗?是的,该财产是公共的。我将再次尝试创建包装器类。上次我可能错过了一些东西。嗯,当我捕获一个新图像时,它只是保存在ObservableCollection中的图像保存在的同一个目录中。因此,我认为我需要更改集合中的项目,而不是集合本身。你的例子很有帮助,谢谢!我将尝试进行您列出的一些更改,看看它们是否有效。我将接受这一点作为答案,因为这有助于我理解我在代码中犯了哪些错误。我仍然无法正确更新UI,但这超出了这个问题的范围,因为它与创建缩略图后未引发的事件有关。
AssetCollection[0].Thumbnail = new BitmapImage(uri);
OnPropertyChanged("AssetCollection");
// Will not raise the CollectionChanged notification
_assetCollection = _assetModel.GetAssetThumbnails();

// Will raise the CollectionChanged notification
AssetCollection = _assetModel.GetAssetThumbnails();