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



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

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

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() {...}

如何实施取决于您。我假设您没有重复项:每个视频都被选中或未被选中,您不能选择和未选择相同的视频。

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

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);
}

选择和取消选择:

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);

TODO:实现 IReadOnlyCollection 等,使用 this.allItems.Keys 获取所有项目。

您的表单类:

private SelectableCollection<Video> videos = new SelectableCollection(this.GetAllVideos());

选择和取消选择:

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;

开始/停止/继续播放视频:

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;
}
}
}

例子:

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();
}

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

最新更新