You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI中CollectionView内MediaElement的播放控制问题

解决方案

1. 给数据模型添加播放状态属性

在FactItem类中新增IsPlaying属性(需实现INotifyPropertyChanged接口,和现有属性保持一致):

private bool _isPlaying;
public bool IsPlaying
{
    get => _isPlaying;
    set
    {
        _isPlaying = value;
        OnPropertyChanged();
    }
}

2. 绑定MediaElement的播放状态

修改XAML中MediaElement的绑定逻辑,将播放状态与数据模型属性关联:

<MediaElement Source="{Binding MediaUrl}" 
              IsPlaying="{Binding IsPlaying}"
              WidthRequest="300" HeightRequest="200" />

3. ViewModel中控制单一视频播放

在MainViewModel中维护当前播放项,确保同一时间只有一个视频播放:

private FactItem _currentPlayingItem;
public FactItem CurrentPlayingItem
{
    get => _currentPlayingItem;
    set
    {
        if (_currentPlayingItem != null)
            _currentPlayingItem.IsPlaying = false;
        
        _currentPlayingItem = value;
        if (_currentPlayingItem != null)
            _currentPlayingItem.IsPlaying = true;
        
        OnPropertyChanged();
    }
}

// 绑定到列表项的点击事件,控制播放/切换
public ICommand PlayCommand => new Command<FactItem>(item =>
{
    CurrentPlayingItem = CurrentPlayingItem == item ? null : item;
});

接着在XAML的ItemTemplate根布局中添加点击手势绑定:

<Grid.GestureRecognizers>
    <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type local:MainViewModel}}, Path=PlayCommand}"
                          CommandParameter="{Binding .}" />
</Grid.GestureRecognizers>

4. 滚动出屏幕自动停止播放

在主页面代码后台(MainPage.xaml.cs)监听CollectionView的可见项变化事件,自动停止非可见项的播放:

private void CollectionView_VisibleItemsChanged(object sender, ItemsViewVisibleItemsChangedEventArgs e)
{
    if (sender is CollectionView cv && cv.BindingContext is MainViewModel vm)
    {
        var visibleItems = cv.VisibleItems.Cast<FactItem>().ToList();
        foreach (var item in vm.FactItems)
        {
            if (!visibleItems.Contains(item) && item.IsPlaying)
            {
                item.IsPlaying = false;
            }
        }
    }
}

然后在XAML中给CollectionView绑定该事件:

<CollectionView ItemsSource="{Binding FactItems}"
                VisibleItemsChanged="CollectionView_VisibleItemsChanged">

关于获取单个MediaElement引用的说明

遵循MVVM原则,不建议在ViewModel中直接引用UI控件。如果确实需要在代码后台操作特定项的MediaElement,可通过Loaded事件建立控件与数据项的关联:

private Dictionary<FactItem, MediaElement> _mediaElementMap = new Dictionary<FactItem, MediaElement>();

private void MediaElement_Loaded(object sender, EventArgs e)
{
    if (sender is MediaElement me && me.BindingContext is FactItem item)
    {
        if (!_mediaElementMap.ContainsKey(item))
            _mediaElementMap.Add(item, me);
    }
}

之后即可通过_mediaElementMap[item]获取对应项的MediaElement控件,执行播放/停止等操作。


内容的提问来源于stack exchange,提问作者Ed Mendez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:06:04