WPFはxamlとC#コードはセットですので、よほど長くない限り一緒に提示してください。
MediaEndedでどういった処理を書けばよいのか分からなくなりました。
Source
に新しいファイルをセットします。
MediaElement.Source プロパティ (System.Windows.Controls) | Microsoft Docs
OpenFileDialog
はWPFにもあるので、System.Windows.Forms
を参照する必要はありません。
OpenFileDialog クラス (Microsoft.Win32) | Microsoft Docs
WPFのMediaElement
はコントローラがないので、最低限の操作だけでも一苦労なんですよねぇ(UWPだと標準でオシャレなコントローラがついているのですが^^;
方法: MediaElement (再生、一時停止、停止、ボリューム、および速度) を制御する - WPF .NET Framework | Microsoft Docs
をベースにまともなシークバーにした参考実装です(シークバーは過去にいろいろ試しましたが、これが一番簡単で分かりやすいと思います)
xml
1<Window
2 x:Class="Questions345578.MainWindow"
3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5 Width="800"
6 Height="450">
7 <Grid>
8 <Grid.ColumnDefinitions>
9 <ColumnDefinition />
10 <ColumnDefinition Width="10" />
11 <ColumnDefinition Width="4*" />
12 </Grid.ColumnDefinitions>
13 <DockPanel>
14 <Button
15 Click="Open_Button_Click"
16 Content="Open"
17 DockPanel.Dock="Bottom" />
18 <ListBox x:Name="TrackList" SelectionChanged="TrackList_SelectionChanged">
19 <ListBox.ItemTemplate>
20 <DataTemplate>
21 <TextBlock Text="{Binding FileName}" ToolTip="{Binding FilePath}" />
22 </DataTemplate>
23 </ListBox.ItemTemplate>
24 </ListBox>
25 </DockPanel>
26 <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" />
27 <DockPanel Grid.Column="2" Background="Black">
28 <StackPanel DockPanel.Dock="Bottom">
29 <ProgressBar
30 x:Name="seekBar"
31 Height="20"
32 MouseDown="SeekBar_MouseDown"
33 MouseMove="SeekBar_MouseMove"
34 MouseUp="SeekBar_MouseUp" />
35 <Grid>
36 <Grid.ColumnDefinitions>
37 <ColumnDefinition />
38 <ColumnDefinition Width="Auto" />
39 <ColumnDefinition />
40 </Grid.ColumnDefinitions>
41 <Slider
42 Name="volumeSlider"
43 Width="100"
44 HorizontalAlignment="Right"
45 VerticalAlignment="Center"
46 Maximum="1"
47 ValueChanged="ChangeVolume"
48 Value="0.5" />
49 <StackPanel
50 Grid.Column="1"
51 HorizontalAlignment="Center"
52 Orientation="Horizontal">
53 <Button Click="OnPrevious" Content="⏮" />
54 <Button Click="OnPlay" Content="⏵" />
55 <Button Click="OnPause" Content="⏸" />
56 <Button Click="OnStop" Content="⏹" />
57 <Button Click="OnNext" Content="⏭" />
58 </StackPanel>
59 <TextBlock
60 x:Name="textBlock"
61 Grid.Column="2"
62 HorizontalAlignment="Right"
63 VerticalAlignment="Center"
64 Foreground="White"
65 Text="0:00:00 / 0:00:00" />
66 </Grid>
67 </StackPanel>
68 <MediaElement
69 Name="mediaElement"
70 LoadedBehavior="Manual"
71 MediaEnded="OnMediaEnded"
72 MediaOpened="OnMediaOpened"
73 ScrubbingEnabled="True"
74 UnloadedBehavior="Stop" />
75 </DockPanel>
76 </Grid>
77</Window>
cs
1using Microsoft.Win32;
2using System;
3using System.IO;
4using System.Windows;
5using System.Windows.Controls;
6using System.Windows.Input;
7using System.Windows.Threading;
8
9namespace Questions345578
10{
11 class Item
12 {
13 public string FilePath { get; set; }
14 public string FileName => Path.GetFileName(FilePath);
15 }
16
17 public partial class MainWindow : Window
18 {
19 private readonly DispatcherTimer timer; // 再生位置監視タイマ
20 private bool isPlaying; // 再生中
21 private bool isDragging; // シークバードラッグ中
22
23 public MainWindow()
24 {
25 InitializeComponent();
26 timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.1), };
27 timer.Tick += Timer_Tick;
28 }
29
30
31 private void Open_Button_Click(object sender, RoutedEventArgs e)
32 {
33 var ofd = new OpenFileDialog
34 {
35 Multiselect = true,
36 InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos),
37 };
38
39 bool? result = ofd.ShowDialog(); // ダイアログを開きます。閉じるまで進みません。
40 if (result == true) // OKの場合true。キャンセル・×の場合false。基本的にnullにはなりません。
41 {
42 foreach (var path in ofd.FileNames)
43 TrackList.Items.Add(new Item { FilePath = path, });
44 }
45 }
46
47 private void TrackList_SelectionChanged(object sender, SelectionChangedEventArgs e)
48 {
49 if (TrackList.SelectedItem is Item item)
50 {
51 mediaElement.Source = new Uri(item.FilePath);
52 mediaElement.Play();
53 isPlaying = true;
54 }
55 }
56
57 private void OnMediaOpened(object sender, EventArgs e)
58 {
59 seekBar.Maximum = mediaElement.NaturalDuration.TimeSpan.TotalMilliseconds; // 総再生ミリ秒
60 seekBar.Value = 0;
61 timer.Start();
62 }
63 private void OnMediaEnded(object sender, EventArgs e)
64 {
65 mediaElement.Stop();
66 timer.Stop();
67 isPlaying = false;
68 OnNext(null, null); // 雑に呼び出しw
69 }
70
71 private void OnPrevious(object sender, RoutedEventArgs e)
72 {
73 mediaElement.Stop();
74 timer.Stop();
75 if (0 < TrackList.SelectedIndex) // 前を選択できれば。。選択
76 TrackList.SelectedIndex--;
77 }
78 private void OnNext(object sender, RoutedEventArgs e)
79 {
80 mediaElement.Stop();
81 timer.Stop();
82 if (TrackList.SelectedIndex < TrackList.Items.Count - 1) // 後を選択できれば。。選択
83 TrackList.SelectedIndex++;
84 }
85
86 private void Timer_Tick(object sender, EventArgs e)
87 {
88 seekBar.Value = mediaElement.Position.TotalMilliseconds;
89 var position = mediaElement.Position; // 再生現在位置
90 var total = mediaElement.NaturalDuration.TimeSpan; // 総再生時間
91 textBlock.Text = $"{position:h\:mm\:ss} / {total:h\:mm\:ss}";
92 }
93
94 private void SeekBar_MouseDown(object sender, MouseButtonEventArgs e)
95 {
96 isDragging = true;
97 seekBar.CaptureMouse(); // MouseUpを確実にとるためキャプチャ
98
99 // 総再生ミリ秒 * シーク位置の割合(例えば真ん中だったら0.5)
100 seekBar.Value = seekBar.Maximum * (e.GetPosition(seekBar).X / seekBar.ActualWidth);
101 mediaElement.Position = TimeSpan.FromMilliseconds(seekBar.Value); // seekBar.Valueはミリ秒単位なので
102
103 mediaElement.Pause(); // PlayしながらシークするとガチャつくのでPause
104 }
105 private void SeekBar_MouseMove(object sender, MouseEventArgs e)
106 {
107 if (isDragging)
108 {
109 seekBar.Value = seekBar.Maximum * (e.GetPosition(seekBar).X / seekBar.ActualWidth);
110 mediaElement.Position = TimeSpan.FromMilliseconds(seekBar.Value);
111 }
112 }
113 private void SeekBar_MouseUp(object sender, MouseButtonEventArgs e)
114 {
115 isDragging = false;
116 seekBar.ReleaseMouseCapture();
117 mediaElement.Position = TimeSpan.FromMilliseconds(seekBar.Value);
118 if (isPlaying) mediaElement.Play(); // Play状態復元
119 }
120
121 private void OnPlay(object sender, RoutedEventArgs args)
122 {
123 mediaElement.Play();
124 timer.Start();
125 isPlaying = true;
126
127 }
128 private void OnPause(object sender, RoutedEventArgs e)
129 {
130 mediaElement.Pause();
131 timer.Stop();
132 isPlaying = false;
133 }
134 private void OnStop(object sender, RoutedEventArgs e)
135 {
136 mediaElement.Stop();
137 timer.Stop();
138 isPlaying = false;
139 }
140
141 private void ChangeVolume(object sender, RoutedPropertyChangedEventArgs<double> args)
142 {
143 if (mediaElement != null)
144 mediaElement.Volume = volumeSlider.Value;
145 }
146 }
147}
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/24 00:26
2021/06/24 10:08