Binding a progressbar to a mediaelement in wpf

后端 未结 5 1499
深忆病人
深忆病人 2020-12-29 13:24

In c#/wpf I added a progressbar and mediaelement to my window. The idea was that progressbar is displaying how much is been played in the mediaelement.

I tried it wi

相关标签:
5条回答
  • 2020-12-29 13:35

    I tried to bind the values and came to this, but without success:

    <ProgressBar 
        x:Name="testProgressBar" Minimum="0" 
        Maximum="{Binding NaturalDuration.TimeSpan.TotalSeconds, ElementName=mediaPlayer}" 
        Value="{Binding Position.TotalSeconds, ElementName=mediaPlayer, Mode=OneWay}" />
    

    Too bad it doesn't work.
    I am afraid that you will need a timer set up.
    Something like:

    *.xaml

    <ProgressBar x:Name="testProgressBar" />
    

    *.cs

        public MainWindow()
        {
            InitializeComponent();
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += timer_Tick;
            timer.Start();
        }
        private void timer_Tick(object sender, EventArgs e)
        {
            if (mediaPlayer.Source != null && mediaPlayer.NaturalDuration.HasTimeSpan)
            {
                testProgressBar.Minimum = 0;
                testProgressBar.Maximum = mediaPlayer.NaturalDuration.TimeSpan.TotalSeconds;
                testProgressBar.Value = mediaPlayer.Position.TotalSeconds;
            }
        }
    

    Kind regards,
    Thimo.

    0 讨论(0)
  • 2020-12-29 13:40

    That is because Media is not opened and hence the progress bar is not aware of the maximum value. Try this...

    Use the following events for MediaOpened, and MouseLeftButtonUp for your progress bar or slider. I tried it, and it works just fine.

    public partial class AudioPage : Page
    {
        TimeSpan _position;
        DispatcherTimer _timer = new DispatcherTimer();
    
        public AudioPage()
        {
            InitializeComponent();
            _timer.Interval = TimeSpan.FromMilliseconds(1000);
            _timer.Tick += new EventHandler(ticktock);
            _timer.Start();
        }
    
        void ticktock(object sender, EventArgs e)
        {
            sliderSeek.Value = media.Position.TotalSeconds;
        }
    
        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }
    
        private void Play_Click(object sender, RoutedEventArgs e)
        {
            media.Play();
        }
    
        private void Pause_Click(object sender, RoutedEventArgs e)
        {
            media.Pause();
        }
    
        private void Stop_Click(object sender, RoutedEventArgs e)
        {
            media.Stop();
        }
    
        private void media_MediaOpened(object sender, RoutedEventArgs e)
        {
            _position = media.NaturalDuration.TimeSpan;
            sliderSeek.Minimum = 0;
            sliderSeek.Maximum = _position.TotalSeconds;
        }
    
        private void sliderSeek_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            int pos = Convert.ToInt32(sliderSeek.Value);
            media.Position = new TimeSpan(0, 0, 0, pos, 0);
        }
    }
    

    The associate XAMl is as follows...

    <Grid x:Name="LayoutRoot" Background="#FFFFE8E8">
        <Grid.RowDefinitions>
            <RowDefinition Height="220*" />
            <RowDefinition Height="75*" />
        </Grid.RowDefinitions>
        <MediaElement Height="189" HorizontalAlignment="Left" Margin="12,12,0,0" Name="media" VerticalAlignment="Top" Width="399" Source="anyfile.mp3" AutoPlay="True" MediaOpened="media_MediaOpened" />
        <StackPanel Orientation="Horizontal" Grid.Row="1" Height="30" Margin="12,8,163,37">
            <TextBlock Text="Volume" VerticalAlignment="Center"></TextBlock>
            <Slider Margin="2" Maximum="1" Minimum="0" Width="102" Value="{Binding Path=Volume, Mode=TwoWay, ElementName=media}"></Slider>
            <TextBlock Text="{Binding ElementName=media, Path=Volume, Mode=OneWay, StringFormat=0.00}" VerticalAlignment="Center" />
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="1" Height="30" Margin="26,47,163,-2">
            <TextBlock Text="Seek" VerticalAlignment="Center"></TextBlock>
            <Slider Margin="2" Width="104" Name="sliderSeek" MouseLeftButtonUp="sliderSeek_MouseLeftButtonUp"></Slider>
            <TextBlock Text="{Binding ElementName=sliderSeek, Path=Value, StringFormat=0}" VerticalAlignment="Center"></TextBlock>
        </StackPanel>
        <StackPanel Orientation="Horizontal" Grid.Row="1" Height="30" Margin="266,8,12,37">
            <Button Name="Play" Content="Play" Margin="2" Click="Play_Click" />
            <Button Name="Pause" Content="Pause" Margin="2" Click="Pause_Click" />
            <Button Name="Stop" Content="Stop" Margin="2" Click="Stop_Click" />
        </StackPanel>
    </Grid>
    
    0 讨论(0)
  • 2020-12-29 13:44

    There is a wrapper library called Gu.Wpf.Media in GitHub that handles all the problems of the MediaElement and brings more.

    It supports binding to Position property via TwoWay binding out of the box. No need to hassle with timers.

    0 讨论(0)
  • 2020-12-29 13:53

    just have look at this example - instead of progressbar he used slider...

    Attaching Preview behavior to a WPF Slider control

    http://jobijoy.blogspot.com/2009/07/attaching-preview-behavior-to-wpf.html

    0 讨论(0)
  • 2020-12-29 13:56

    A WPF version of Rahul's sample with added real-time change of media position while sliding the bar.

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
    
            _timer.Interval = TimeSpan.FromMilliseconds(1000);
            _timer.Tick += new EventHandler(ticktock);
            _timer.Start();
    
            Open(@"filename.mp3");
        }
        public void Open(string fileName)
        {
            var uriPath = "file:///" + fileName.Replace("\\", "/");
            media.Source=new Uri(uriPath);
        }
    
        TimeSpan _position;
        DispatcherTimer _timer = new DispatcherTimer();
    
        void ticktock(object sender, EventArgs e)
        {
            if (!sliderSeek.IsMouseCaptureWithin)
                sliderSeek.Value = media.Position.TotalSeconds;
        }
    
        private void Play_Click(object sender, RoutedEventArgs e)
        {
            media.Play();
        }
    
        private void Pause_Click(object sender, RoutedEventArgs e)
        {
            media.Pause();
        }
    
        private void Stop_Click(object sender, RoutedEventArgs e)
        {
            media.Stop();
        }
    
        private void media_MediaOpened(object sender, RoutedEventArgs e)
        {
            _position = media.NaturalDuration.TimeSpan;
            sliderSeek.Minimum = 0;
            sliderSeek.Maximum = _position.TotalSeconds;
        }
    
        private void sliderSeek_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {           
            int pos = Convert.ToInt32(sliderSeek.Value);
            media.Position = new TimeSpan(0, 0, 0, pos, 0);
        }
    
        private void sliderSeek_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (sliderSeek.IsMouseCaptureWithin)
            {
                int pos = Convert.ToInt32(sliderSeek.Value);
                media.Position = new TimeSpan(0, 0, 0, pos, 0);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题