更新后清爽UI到ListBox绑定集合(Refreshing UI after update to

2019-09-27 20:21发布

我试图在视觉上显示的项目(在我的情况下的BitmapImage)已被添加到一个集合中使用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;
}

我的视图模型建立在其构造模型的新实例,然后设置公共财产AssetCollection等于_assetModel.GetAssetThumbnails() 该视图模型具有所有标准OnPropertyChanged事件和事件处理。

private void OnPropertyChanged(string propertyName)
{
    if(PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

#region Public Properties
public ObservableCollection<BitmapImage> AssetCollection
{
    get { return _assetCollection; }
    set
    {
        if (_assetCollection != value)
        {
            _assetCollection = value;
            OnPropertyChanged("AssetCollection");    
        }
    }
}
#endregion

private void _assetCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    OnPropertyChanged("AssetCollection");
}
public event PropertyChangedEventHandler PropertyChanged;

然后,在我的XAML文件,我绑定ListBox的项目源AssetCollection。

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

我读过,集合中的每个项目应实现INotifyPropertyChanged接口。 我试图创建为实现一个位图图像的包装类,但它也不能工作。 有没有办法,我缺少的东西在这里? 这些图像显示了最初,但图像已经被捕获并保存后,不要刷新。 我有一种感觉它从事件所产生PropertyChanged没有得到调用。 我通过调试,当它的检查,因此,它始终是空注意到OnPropetyChanged方法不会被调用。 我不知道我应该在哪里,虽然添加此事件处理程序。 我只用代码隐藏文件中添加视图模型到视图的数据上下文,这就是它。 这就是我通常会想添加任何事件处理。 任何人都可以看到,我在这里失踪简单的东西?

Answer 1:

你改变ObservableCollection ,当你更新列表,或者是你改变存储在集合里面的物品?

如果您要改变集合里面的物品,你需要找到一种方法来告诉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");
}

如果项目没有实现INotifyPropertyChanged ,你必须手动提升CollectionChanged事件随时随地的项目在收集变化。

AssetCollection[0].Thumbnail = new BitmapImage(uri);
OnPropertyChanged("AssetCollection");

如果您正在改变ObservableCollection通过添加/删除项目本身并没有看到UI更新,那么它听起来像它可能是一个语法错误的地方,我们看不到。

最常见的一个我看到的是制作和更改私有财产而不是公共财产。

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

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

虽然我也看到很多人谁使用List或定制的集合,而不是一个的ObservableCollection以及,这不会引发CollectionChanged事件。



文章来源: Refreshing UI after update to a ListBox-bound collection