MediaPlaybackList变更通知未同步至ListView的问题求助
解决MediaPlaybackList变更未通知绑定ListView的问题
嘿,我之前也踩过这个坑!核心问题在于MediaPlaybackList的Items集合本身不支持INotifyCollectionChanged接口——这意味着你往里面加、删、改MediaPlaybackItem的时候,绑定的ListView根本感知不到变化,自然不会更新。
下面给你两种靠谱的解决思路,选哪种看你的需求:
方法一:用ObservableCollection做中间层(推荐)
我们可以自己维护一个支持变更通知的ObservableCollection,同步MediaPlaybackList的Items,然后把ListView绑定到这个集合上。这样既保留了MediaPlaybackList的原生功能,又能让ListView实时响应变化。
ViewModel代码示例:
using System.Collections.ObjectModel; using Windows.Media.Playback; public class YourPlayListViewModel { // 供ListView绑定的可观察集合 private ObservableCollection<MediaPlaybackItem> _playbackItems; public ObservableCollection<MediaPlaybackItem> PlaybackItems { get => _playbackItems; set { _playbackItems = value; // 如果用了MVVM框架(比如Prism、MvvmLight),这里调用对应的属性变更通知方法 // 比如 RaisePropertyChanged(nameof(PlaybackItems)); } } // 原生的MediaPlaybackList,供MediaPlayerElement绑定 public MediaPlaybackList MediaPlaybackList { get; } public YourPlayListViewModel() { MediaPlaybackList = new MediaPlaybackList(); // 初始化可观察集合 _playbackItems = new ObservableCollection<MediaPlaybackItem>(MediaPlaybackList.Items); // 订阅MediaPlaybackList的ItemsChanged事件,同步集合 MediaPlaybackList.ItemsChanged += MediaPlaybackList_ItemsChanged; } private void MediaPlaybackList_ItemsChanged(MediaPlaybackList sender, ItemsChangedEventArgs args) { // 根据不同的变更类型更新ObservableCollection switch (args.Action) { case ItemsChangedAction.Add: PlaybackItems.Insert(args.Index, sender.Items[args.Index]); break; case ItemsChangedAction.Remove: PlaybackItems.RemoveAt(args.Index); break; case ItemsChangedAction.Move: var movedItem = PlaybackItems[args.OldIndex]; PlaybackItems.RemoveAt(args.OldIndex); PlaybackItems.Insert(args.Index, movedItem); break; case ItemsChangedAction.Replace: PlaybackItems[args.Index] = sender.Items[args.Index]; break; case ItemsChangedAction.Reset: PlaybackItems.Clear(); foreach (var item in sender.Items) { PlaybackItems.Add(item); } break; } } // 记得在ViewModel销毁时取消订阅,避免内存泄漏 public void Cleanup() { MediaPlaybackList.ItemsChanged -= MediaPlaybackList_ItemsChanged; } }
对应的XAML修改:
把ListView的ItemsSource绑定到我们的PlaybackItems集合:
<ListView x:Name="PlayListView" ItemsSource="{x:Bind ViewModel.PlaybackItems, Mode=OneWay}"> <!-- 你的ItemTemplate内容 --> </ListView>
方法二:手动触发ListView绑定刷新(简单但不优雅)
如果不想折腾ObservableCollection,也可以在MediaPlaybackList的ItemsChanged事件里,手动重置ListView的数据源。这种方式虽然简单,但会导致整个列表重新加载,可能有视觉闪烁或者性能问题,适合小型列表场景。
代码示例(在用户控件的代码后台):
public YourPlayListControl() { this.InitializeComponent(); // 假设ViewModel已经初始化,订阅ItemsChanged事件 ViewModel.MediaPlaybackList.ItemsChanged += MediaPlaybackList_ItemsChanged; } private void MediaPlaybackList_ItemsChanged(MediaPlaybackList sender, ItemsChangedEventArgs args) { // 先清空数据源,再重新赋值,触发绑定刷新 PlayListView.ItemsSource = null; PlayListView.ItemsSource = sender.Items; }
最后提醒一句:不管用哪种方法,都要记得在页面/控件销毁时取消订阅ItemsChanged事件,不然容易出现内存泄漏哦!
内容的提问来源于stack exchange,提问作者user6189573
相关产品推荐
相关产品推荐

