gpt4 book ai didi

wpf - 更新到 ListBox 绑定(bind)集合后刷新 UI

转载 作者:行者123 更新时间:2023-12-03 10:29:58 25 4
gpt4 key购买 nike

我试图直观地显示一个项目(在我的情况下为 BitmapImage)已使用 WPF/MVVM 添加到 ListBox 中的集合中。为了提供一些背景知识,我正在使用采集卡捕获流式视频,并且在视频流式传输时拍摄静止图像。这些图像是通过单击 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;
}

我的 ViewModel 在其构造函数中创建模型的新实例,然后设置公共(public)属性 AssetCollection等于 _assetModel.GetAssetThumbnails() . ViewModel 具有所有标准的 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 的项目源绑定(bind)到 AssetCollection。
<ListBox x:Name="lstBoxAssets" ItemsSource="{Binding AssetCollection}" Grid.Row="1" Background="{DynamicResource GrayColor}" Margin="5,0,0,5" ></ListBox>   

我读过集合中的每个项目都应该实现 INotifyPropertyChanged 接口(interface)。我尝试为实现它的位图图像创建一个包装器类,但它也不起作用。有什么我在这里想念的吗?图像最初会显示,但在捕获并保存图像后不会刷新。我感觉它源于事件 PropertyChanged没有被叫。我通过调试注意到它在检查时始终为空,因此 OnPropetyChanged方法永远不会被调用。我不确定我应该在哪里添加这个事件处理程序。我只使用代码隐藏文件将 View 模型的数据上下文添加到 View 中,仅此而已。这就是我通常认为添加任何事件处理的地方。谁能看到我在这里遗漏的一些简单的东西?

最佳答案

您是否正在更改 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 更新,那么听起来它可能是我们看不到的地方的语法错误。

我看到的最常见的一种是更改私有(private)属性(property)而不是公共(public)属性(property)。
// Will not raise the CollectionChanged notification
_assetCollection = _assetModel.GetAssetThumbnails();

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

虽然我也看到很多人使用 List或自定义集合而不是 ObservableCollection同样,这不会引发 CollectionChanged事件。

关于wpf - 更新到 ListBox 绑定(bind)集合后刷新 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9469056/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com