2010-10-30 47 views
8

Trong C#/wpf tôi đã thêm thanh tiến trình và mediaelement vào cửa sổ của mình. Ý tưởng là thanh tiến trình hiển thị số lượng được phát trong phần đa phương tiện.Gắn thanh tiến trình vào phần đa phương tiện trong wpf

Tôi đã thử nó với XAML sau:

<Window x:Class="TestApp.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="627" Width="889"> 
    <Grid> 
    <MediaElement Margin="152,8,140,41" Name="mediaElement1" MediaEnded="mediaElement1_MediaEnded" Visibility="Hidden" /> 
    <ProgressBar Height="23" Margin="152,8,10,0" Name="mp3PlayingProgressBar" VerticalAlignment="Top" Foreground="DarkBlue" Maximum="{Binding Path=NaturalDuration.TimeSpan.TotalSeconds, Mode=OneWay, ElementName=mediaElement1}" Value="{Binding Path=Position.TotalSeconds, Mode=OneWay, ElementName=mediaElement1}" /> 
    </Grid> 
</Window> 

tôi đã cố gắng để ràng buộc các tài sản cho MediaElement tối đa và giá trị gia tăng. Nhưng khi tôi tải một mp3 ví dụ vào mediaelement, không có gì happends với progressbar. (Nhạc đang phát để nhạc mp3 được tải và phát một cách chính xác).

Tôi muốn thực hiện việc này bằng cách ràng buộc.

Tôi đang làm gì ở đây sai?

Trả lời

10

Đó là vì Phương tiện không được mở và do đó thanh tiến trình không nhận thức được giá trị tối đa. Hãy thử điều này ...

Sử dụng các sự kiện sau cho MediaOpened và MouseLeftButtonUp cho thanh tiến trình hoặc thanh trượt của bạn. Tôi đã thử nó, và nó hoạt động tốt.

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

Các sư XAML là như sau ...

<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

Bạn đang cập nhật giá trị bằng bộ hẹn giờ. Tôi thích làm điều đó với một ràng buộc. Không phải là có thể? –

+1

Tôi thực sự không thể nói nếu có thể hay không. Nhưng tôi đã viết giải pháp này vì tôi không thể làm cho nó hoạt động với Binding.Tôi nhận ra rằng vấn đề đã xảy ra bởi vì phương tiện truyền thông không được mở và tôi đã chọn viết mã này. Ai đó có thể sửa tôi và cung cấp giải pháp tốt hơn. Tôi sẽ tiếp tục theo dõi chủ đề này. –

4

Tôi đã cố gắng liên kết v alues ​​và đến điều này, nhưng không thành công:

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

Quá xấu nó không hoạt động.
Tôi sợ rằng bạn sẽ cần thiết lập hẹn giờ.
Cái gì như:

* .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.

+2

Không? Tôi đã cố gắng những gì người muốn biết, mà không làm việc, do đó tôi đã đưa ra một thay thế cho câu hỏi. cái nào có tác dụng và có hiệu quả mà người ta đặt câu hỏi mong muốn đạt được, phải không? Tôi chỉ cố gắng giúp người yêu cầu giúp đỡ, và trong mắt tôi đó là một câu trả lời. Đọc nó tốt. Nó chỉ đơn giản là không thể ràng buộc giá trị của thời gian đã được truyền trong trình phát media trực tiếp đến thanh tiến trình, do một số quyết định kỳ quặc mà Microsoft đưa ra. –

+1

Đây là câu trả lời và thực sự là câu trả lời hay! Tôi đã có chính xác trường hợp của OP và câu trả lời này được giải quyết làm việc chính xác như thế nào tôi muốn nó cho giải pháp của tôi. :) – Milkncookiez

0

Phiên bản WPF của mẫu Rahul có thay đổi thời gian thực của vị trí phương tiện trong khi trượt thanh.

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

Có một thư viện wrapper gọi Gu.Wpf.Media trong GitHub để xử lý tất cả các vấn đề của MediaElement và mang lại nhiều hơn nữa.

Hỗ trợ liên kết với Position thuộc tính qua TwoWay ràng buộc ra khỏi hộp. Không cần phải rắc rối với bộ hẹn giờ.

Các vấn đề liên quan