WPFみたいにPreview
系のイベントがないのがつらいですね^^;
SliderのValueがつまみを動かすことによって変更されたということを検知する方法がわかりませんでした。
Slider
のテンプレートを見ると、CommonStates.Pressed
で検知できそうです。
microsoft-ui-xaml/Slider_themeresources.xaml at main · microsoft/microsoft-ui-xaml
PlaybackSession.PositionChanged
はあんまりスムーズではなかったので、単純にタイマーにしました(が、処理が甘いかもw
xml
1 < windowex: WindowEx
2 x: Class = " Qbcc389s6g38ght.MainWindow "
3 xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
4 xmlns: x = " http://schemas.microsoft.com/winfx/2006/xaml "
5 xmlns: windowex = " using:WinUIEx "
6 Width = " 800 "
7 Height = " 450 " >
8
9 < Grid RowDefinitions = " *,Auto " >
10 < MediaPlayerElement x: Name = " mpe " Source = " ms-appx:///Assets/SampleMedia/ladybug.wmv " />
11
12 < StackPanel Grid.Row = " 1 " Margin = " 8 " >
13 < Slider
14 x: Name = " slider "
15 Loaded = " Slider_Loaded "
16 ValueChanged = " Slider_ValueChanged " />
17
18 < ToggleButton
19 x: Name = " toggleButton "
20 HorizontalAlignment = " Center "
21 Checked = " ToggleButton_Checked "
22 Content = " Play/Pause "
23 Unchecked = " ToggleButton_Unchecked " />
24 </ StackPanel >
25 </ Grid >
26 </ windowex: WindowEx >
cs
1 using System ;
2 using System . Linq ;
3 using Microsoft . UI . Dispatching ;
4 using Microsoft . UI . Xaml ;
5 using Microsoft . UI . Xaml . Controls . Primitives ;
6 using Microsoft . UI . Xaml . Media ;
7 using Windows . Media . Playback ;
8
9 namespace Qbcc389s6g38ght ;
10
11 public sealed partial class MainWindow //: Window
12 {
13 private readonly DispatcherTimer timer ;
14 private bool isPlaying ;
15
16 public MainWindow ( )
17 {
18 InitializeComponent ( ) ;
19
20 mpe . MediaPlayer . MediaOpened += MediaPlayer_MediaOpened ;
21 mpe . MediaPlayer . MediaEnded += MediaPlayer_MediaEnded ;
22
23 mpe . MediaPlayer . PlaybackSession . PlaybackStateChanged += PlaybackSession_PlaybackStateChanged ;
24
25 timer = new DispatcherTimer { Interval = TimeSpan . FromMilliseconds ( 100 ) , } ;
26 timer . Tick += Timer_Tick ;
27 }
28
29
30 private void Slider_Loaded ( object sender , RoutedEventArgs e )
31 {
32 var firstChild = VisualTreeHelper . GetChild ( slider , 0 ) as FrameworkElement ;
33 var commonStates = VisualStateManager . GetVisualStateGroups ( firstChild )
34 . First ( x => x . Name == "CommonStates" ) ;
35 commonStates . CurrentStateChanged += CommonStates_CurrentStateChanged ;
36 }
37 private void CommonStates_CurrentStateChanged ( object sender , VisualStateChangedEventArgs e )
38 {
39 if ( e . NewState . Name == "Pressed" )
40 {
41 isPlaying = mpe . MediaPlayer . PlaybackSession . PlaybackState == MediaPlaybackState . Playing ;
42 mpe . MediaPlayer . Pause ( ) ;
43 }
44 else if ( e . NewState . Name == "Normal" )
45 {
46 if ( isPlaying ) mpe . MediaPlayer . Play ( ) ;
47 }
48 }
49
50 private void MediaPlayer_MediaOpened ( MediaPlayer sender , object args )
51 {
52 DispatcherQueue ?. TryEnqueue ( DispatcherQueuePriority . Normal , ( ) =>
53 {
54 slider . Maximum = mpe . MediaPlayer . PlaybackSession . NaturalDuration . TotalMilliseconds ;
55 } ) ;
56 }
57 private void MediaPlayer_MediaEnded ( MediaPlayer sender , object args )
58 {
59 DispatcherQueue ?. TryEnqueue ( DispatcherQueuePriority . Normal , ( ) =>
60 {
61 slider . Value = 0 ;
62 toggleButton . IsChecked = false ;
63 } ) ;
64 }
65
66 private void PlaybackSession_PlaybackStateChanged ( MediaPlaybackSession sender , object args )
67 {
68 DispatcherQueue ?. TryEnqueue ( DispatcherQueuePriority . Normal , ( ) =>
69 {
70 if ( mpe . MediaPlayer . PlaybackSession . PlaybackState == MediaPlaybackState . Playing )
71 timer . Start ( ) ;
72 else
73 timer . Stop ( ) ;
74 } ) ;
75 }
76
77 private void Timer_Tick ( object sender , object e )
78 => slider . Value = mpe . MediaPlayer . PlaybackSession . Position . TotalMilliseconds ;
79
80 private void Slider_ValueChanged ( object sender , RangeBaseValueChangedEventArgs e )
81 => mpe . MediaPlayer . PlaybackSession . Position = TimeSpan . FromMilliseconds ( slider . Value ) ;
82
83 private void ToggleButton_Checked ( object sender , RoutedEventArgs e ) => mpe . MediaPlayer . Play ( ) ;
84 private void ToggleButton_Unchecked ( object sender , RoutedEventArgs e ) => mpe . MediaPlayer . Pause ( ) ;
85 }
NuGet Gallery | WinUIEx 2.1.0
わたしも今MediaTransportControls
で見切れるシークバー(↓のようなの)を作ってるんですが、隠れると位置が更新されなくて頭を抱えました(結局2重にSlider
を付けたw
[WPF] 動画プレイヤー 表示/非表示できる操作画面を作りたい
ThumbnailRequested もタップした時しか来ないとか意味が分からんし...