C# 如何移动到列表中的下一项

C# 如何移动到列表中的下一项,c#,winforms,C#,Winforms,因此,作为培训的一部分,我必须创建一个利用Xbox Api的程序。它的工作原理是,用户搜索玩家标签,并调出所有用户最近上传的游戏剪辑。然后,您可以选择一个剪辑,它将在我添加的Windows Media Player控件中播放 现在我正在尝试将其设置为自动播放下一个视频。我如何填写下面的方法来自动播放列表中的下一个项目,请记住它不会循环播放列表中的所有视频,而只是从用户选择的位置开始 private void wmpClip_PlayStateChange(object sender,

因此,作为培训的一部分,我必须创建一个利用Xbox Api的程序。它的工作原理是,用户搜索玩家标签,并调出所有用户最近上传的游戏剪辑。然后,您可以选择一个剪辑,它将在我添加的Windows Media Player控件中播放

现在我正在尝试将其设置为自动播放下一个视频。我如何填写下面的方法来自动播放列表中的下一个项目,请记住它不会循环播放列表中的所有视频,而只是从用户选择的位置开始

private void wmpClip_PlayStateChange(object sender,
                                     AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
    if (wmpClip.playState == WMPLib.WMPPlayState.wmppsMediaEnded)
    {
        //play next video in list
    }
}
因此,以下代码是搜索剪辑时搜索方法的一部分:

foreach (var video in videos)
            {
                ctrlSearchResults searchResult = new ctrlSearchResults();
                searchResult.SetDetails(video);
                flpSearchResults.Controls.Add(searchResult);
                searchResult.OnVideoSelected += SearchResult_OnVideoSelected;
                //Limit to save api requests
                if (flpSearchResults.Controls.Count == 3)
                {
                    break;
                }
            }
然后,当用户单击“流布局”面板上列表中的视频时,将运行以下代码:

private void SearchResult_OnVideoSelected(Video obj)
        {
            wmpClip.Visible = true;
            wmpClip.URL = obj.gameClipUris[0].uri;
            pnlVideoInfo.Visible = true;
            lblClipName.Visible = true;
            lblActualLength.Text = obj.durationInSeconds.ToString();
            lblActualSize.Text = (obj.gameClipUris[0].fileSize / 1024 / 1024).ToString() + "mb";
            lblActualDate.Text = obj.datePublished.ToString();
            lblActualGame.Text = obj.titleName;
            lblActualViews.Text = obj.views.ToString();
            lblActualRating.Text = obj.rating.ToString();
            lblActualLikes.Text = obj.likeCount.ToString();
            lblClipName.Text = obj.clipName;

            GamerCard gamer = _clipsApi.GetGamerCardByXUID(obj.xuid.ToString());
            pnlGamerInfo.Visible = true;
            pbGamerPic.Load(gamer.gamerpicLargeSslImagePath);
            lblGamerTag.Text = gamer.gamertag;
            lblGamerScore.Text = gamer.gamerscore.ToString();
            lblActualLocation.Text = gamer.location;
            txtBio.Text = gamer.bio;
        }
我希望这是有意义的。

你应该努力解决你的问题:把你的大问题分成小问题,为每个小问题发明一个独立的解决方案。这使得实现更容易理解,更容易重用、测试、更改等

所以,让我们分开你的顾虑

显然,您可以将所有视频作为一个序列进行提取:

IEnumerable<Video> GetAllVideos() {...}
IEnumerable GetAllVideos(){…}
如何实现这一点取决于您。我假设您在这方面没有重复:每个视频要么被选中,要么未被选中,您不能选择相同的视频以及未被选中的视频

让我们为视频创建一个集合类,您可以在其中选择和取消选择视频。 事实上:让我们使其可重用:一个包含 可以选择和取消选择:

public SelectableCollection<T>
    // only if desired
    : IReadonlyCollection<T>, IReadonlyList<T>, IEnumerable<T>
{
    private readonly Dictionary<T, bool> allItems;

    public SelectableCollection() : this(Enumerable.Empty<T>()) {}

    public SelectableCollection(IEnumerable<T> collection) : this (collection, null) {}

    public SelectableCollection(IEnumerable<T> source, IEqualityComparer<T> comparer = null)
    {
        // TODO: check source not null
        if (comparer == null) comparer = EqualityComparer<T>.Default;

         // initially nothing selected:
        this.AllItems = source.ToDictionary(video => video, false, comparer);
    }
public SelectableCollection
//只有在需要的时候
:IReadonlyCollection、IReadonlyList、IEnumerable
{
专用只读词典;
public SelectableCollection():此(Enumerable.Empty()){}
public SelectableCollection(IEnumerable collection):此(collection,null){}
公共SelectableCollection(IEnumerable源,IEqualityComparer比较器=null)
{
//TODO:检查源不为空
如果(comparer==null)comparer=EqualityComparer.Default;
//最初未选择任何内容:
this.AllItems=source.ToDictionary(video=>video,false,comparer);
}
选择并取消选择:

bool IsSelected(T item)
{
    // TODO: decide what if item does not exist
    return this.allItems[item];
}

bool Select(T item)
{
    // TODO: decide what if item does not exist
    this.allItems[item] = true;
}

bool UnSelect(T item)
{
    // TODO: decide what if item does not exist
    this.allItems[item] = false;
}

IEnumerable<T> SelectedItems => this.allItems
    // Key is T, Value is boolean Selected
    .Where(keyValuePair => keyValuePair.Value)
    .Select(keyValuePair => keyValuePair.Key);
bool IsSelected(Video video)
{
    return this.videos.IsSelected(video);
}

bool Select(Video video)
{
    this.videos.Select(video);
}

bool UnSelect(Video video)
{
    this.videos.UnSelect(video);
}

IEnumerable<Video> SelectedVideos => this.videos.SelectedItems;
bool被选中(T项)
{
//TODO:决定如果项目不存在该怎么办
返回此。allItems[项目];
}
布尔选择(T项)
{
//TODO:决定如果项目不存在该怎么办
this.allItems[项]=true;
}
bool取消选择(T项)
{
//TODO:决定如果项目不存在该怎么办
this.allItems[项]=false;
}
IEnumerable SelectedItems=>this.allItems
//键为T,值为布尔值
.Where(keyValuePair=>keyValuePair.Value)
.选择(keyValuePair=>keyValuePair.Key);
TODO:实现IReadOnlyCollection等。使用this.allItems.Keys获取所有项目

你的表格类别:

private SelectableCollection<Video> videos = new SelectableCollection(this.GetAllVideos());
private-SelectableCollection-videos=new-SelectableCollection(this.GetAllVideos());
选择并取消选择:

bool IsSelected(T item)
{
    // TODO: decide what if item does not exist
    return this.allItems[item];
}

bool Select(T item)
{
    // TODO: decide what if item does not exist
    this.allItems[item] = true;
}

bool UnSelect(T item)
{
    // TODO: decide what if item does not exist
    this.allItems[item] = false;
}

IEnumerable<T> SelectedItems => this.allItems
    // Key is T, Value is boolean Selected
    .Where(keyValuePair => keyValuePair.Value)
    .Select(keyValuePair => keyValuePair.Key);
bool IsSelected(Video video)
{
    return this.videos.IsSelected(video);
}

bool Select(Video video)
{
    this.videos.Select(video);
}

bool UnSelect(Video video)
{
    this.videos.UnSelect(video);
}

IEnumerable<Video> SelectedVideos => this.videos.SelectedItems;
bool被选中(视频)
{
返回此.videos.IsSelected(视频);
}
布尔选择(视频)
{
此。视频。选择(视频);
}
布尔取消选择(视频)
{
此.videos.UnSelect(视频);
}
IEnumerable SelectedVideos=>this.videos.SelectedItems;
开始/停止/继续播放视频:

class VideoPlayer
{
    private List<Video> VideosToPlay {get; set;}
    private int IndexNextVideoToPlay {get; set;}

    void StartPlayingVideos(IEnumerable<Video> videos)
    {
        this.VideosToPlay = this.SelectedVideos.ToList();
        this.IndexNextVideoToPlay = 0;
    }

    private void PlayNextVideo()
    {
        if (this.IndexNextVideoToPlay < this.VideosToPlay.Count)
        {
            this.Play(this.VideosToPlay[this.IndexNextVideoToPlay];
            ++this.IndexNextVideoToPlay;
        }
    }
}
class视频播放器
{
私有列表VideosToPlay{get;set;}
private int IndexNextVideoToPlay{get;set;}
无效开始播放视频(IEnumerable视频)
{
this.VideosToPlay=this.SelectedVideos.ToList();
this.IndexNextVideoToPlay=0;
}
私有void PlayNextVideo()
{
if(this.IndexNextVideoToPlay
示例:

private void OnButtonClicked(object sender, EventArgs e)
{
     // user finished selecting videos in the listbox. Mark them as selected
     IEnumerable<Video> selectedVideos = this.listBox1.SelectedItems.Cast<Video>();

     // TODO: select all selectedVideos; Unselect all not-selected videos.         
}

private void OnVideoFinished(object sender, EventArgs e)
{
    this.VideoPlayer.PlayNextVideo();
}
private void OnButtonClicked(对象发送方,事件参数e)
{
//用户已完成在列表框中选择视频。将其标记为已选择
IEnumerable selectedVideos=this.listBox1.SelectedItems.Cast();
//TODO:选择所有选定的视频;取消选择所有未选定的视频。
}
私有void OnVideoFinished(对象发送方,事件参数e)
{
这个.VideoPlayer.PlayNextVideo();
}

结论:把你的问题分成几个小的子问题。毫不犹豫地创建一个类来解决你的子问题。通常这些类只有一个小任务,几乎不依赖其他类。因此,你的类将易于理解、易于创建、易于重用、易于测试和维护。

你能发布更多的代码吗at是wmpClip的类型吗?@EyIM我添加了更多代码flpSearchResults的类型是什么?它是类成员吗?