Событие WPF Mediaelement mediaopened не запускается из-за кода, а из обработчика нажатия кнопки

Первый пост, так что будьте нежны и извините за длинный пост, но хотел предоставить как можно больше подробностей.

У меня есть элемент управления MediaElement внутри пользовательского элемента управления со свойством LoadedBehaviour, установленным вручную, см. ниже. Когда я нажимаю кнопку «Открыть», код обработчика включает воспроизведение мультимедиа, чтобы я мог подготовить свойство продолжительности в обработчике событий MediaOpened, что он успешно делает. Обработчик MediaOpened останавливает воспроизведение, когда мне просто требуется длина носителя.

Я также хочу загрузить список воспроизведения в начале программы и заполнить сетку данных информацией, одним из элементов которой является длина носителя.

XAML

    <MediaElement Grid.Row="5" Name="MediaEL" Grid.ColumnSpan="6" MediaOpened="MediaEL_MediaOpened"  LoadedBehavior="Manual" Height="169" />

    <DataGrid Grid.Row="1" Grid.ColumnSpan="6"  Name="dgPlayList" AutoGenerateColumns="False" Height="300" >
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Position}" Header="#" Width="30"/>
            <DataGridTextColumn Binding="{Binding Title}" Header="Title" Width="182"/>
            <DataGridTextColumn Binding="{Binding Time}" Header="Time" Width="50"/>
            <DataGridCheckBoxColumn Binding="{Binding Dnp}" Header="Dnp" Width="35"/>
            <DataGridTextColumn Binding="{Binding Location}" Visibility="Hidden" />
        </DataGrid.Columns>
    </DataGrid>

C#

    private void btnOpen_Click(object sender, RoutedEventArgs e)  
    {  
        System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();  

        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)  
        {  
            MediaEL.Source = new Uri(ofd.FileName);
            btnPlay.IsEnabled = true;
            MediaEL.Visibility = Visibility.Hidden;
            SettingTime = true;
            MediaEL.Play();
        }
    }

    private void MediaEL_MediaOpened(object sender, RoutedEventArgs e)
    {
        if (MediaEL.NaturalDuration.HasTimeSpan)
        {
            TimeSpan ts = MediaEL.NaturalDuration.TimeSpan;
            Length.Content = FormatLength(ts.TotalSeconds);  // make it look like 00:00:00
            seekBar.Maximum = ts.TotalSeconds;
            seekBar.SmallChange = 1;
            seekBar.LargeChange = Math.Min(10, ts.Seconds / 10);
        }
        if (!SettingTime)
            timer.Start();
        else
        {
            SettingTime = false;
            MediaEL.Stop();
            MediaEL.Visibility = Visibility.Visible;
            MediaEL.Close();
        }
    }

dgPlayList.ItemsSource = LoadPlayListData();

вызывается в методе загрузки окна.
Я закомментировал метод под оператором foreach, пока не заработаю.

Теперь ПРОБЛЕМА заключается в том, что при попытке получить длину носителя для заполнения столбца времени сетки данных событие MediaOpened НЕ срабатывает, и я не понимаю, почему это не так, и исчерпал поиск по этому вопросу.
Любые мысли будут очень признательны!
Спасибо, Джим

C#

    private ObservableCollection<PlayListEntry> LoadPlayListData()
    {
        var playListEntries = new ObservableCollection<PlayListEntry>();
        var position = 1;
        var bPlay = false;

        var doc = new XmlDocument();
        doc.Load(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase) + @"/mpcplaylist.xml");

        var root = doc.DocumentElement;
        var nodes = root.SelectNodes("/playlist/media");

        XmlNode node = nodes[0];

        if (node.InnerXml.Contains("title"))
        {
            var xmlElement = node["title"];
            if (xmlElement != null)
                Title = xmlElement.InnerText;
        }

        if (node.InnerXml.Contains("artist"))
        {
            var xmlElement = node["artist"];
            if (xmlElement != null)
                Artist = xmlElement.InnerText;
        }

        if (node.InnerXml.Contains("location"))
        {
            var xmlElement = node["location"];
            if (xmlElement != null)
                Location = xmlElement.InnerText;
        }

        if (node.InnerXml.Contains("include"))
        {
            var xmlElement = node["include"];
            if (xmlElement != null)
                Include = xmlElement.InnerText;
        }

        if (Include == "No")
            bPlay = true;
        else
            bPlay = false;

        //foreach (XmlNode node in nodes)
        //{
        //    if (node.InnerXml.Contains("title"))
        //    {
        //        var xmlElement = node["title"];
        //        if (xmlElement != null)
        //            Title = xmlElement.InnerText;
        //    }

        //    if (node.InnerXml.Contains("artist"))
        //    {
        //        var xmlElement = node["artist"];
        //        if (xmlElement != null)
        //            Artist = xmlElement.InnerText;
        //    }

        //    if (node.InnerXml.Contains("location"))
        //    {
        //        var xmlElement = node["location"];
        //        if (xmlElement != null)
        //            Location = xmlElement.InnerText;
        //    }

        //    if (node.InnerXml.Contains("include"))
        //    {
        //        var xmlElement = node["include"];
        //        if (xmlElement != null)
        //            Include = xmlElement.InnerText;
        //    }

        //    if (Include == "No")
        //        bPlay = true;
        //    else
        //        bPlay = false;


            MediaEL.Source = new Uri(Location);

            SettingTime = true;

            MediaEL.Play();

            Medialength = Length.Content.ToString();

            playListEntries.Add(new PlayListEntry()
            {
                Dnp = bPlay,
                Position = position++,
                Time = Medialength,
                Title = Title,
                Location = Location
            });


        //}

        return playListEntries;
    }

person Jim    schedule 01.02.2013    source источник
comment
Странно, что вы не получили отзыва здесь... У меня похожая проблема, и я свяжусь с вами, когда найду решение.   -  person Sheridan    schedule 19.02.2013


Ответы (2)


Решение было...

Я беру первую запись из списка воспроизведения xml и устанавливаю свойство источника, а затем вызываю метод воспроизведения, чтобы получить продолжительность. Теперь в событии Media Opened я затем беру следующую запись и делаю то же самое, пока не получу продолжительность для всех элементов мультимедиа в списке.

Это был ключ к тому, чтобы событие открытия носителя получало следующую запись после обработки первой.

Тем не менее, у меня есть еще одна проблема с потоками и управлением, но я создам для этого новый пост.

Спасибо, Джим

person Jim    schedule 14.03.2013

Итак, мне не удалось найти полное решение моей версии вашей проблемы, но я определил причину моей проблемы с объектом MediaPlayer. Мое приложение (и внутренний медиаплеер) работали нормально, но перестали работать после того, как были изменены разрешения на папку, содержащую звук.

Папка была изменена, чтобы разрешить доступ только для чтения, поэтому mediaPlayer все еще должен был иметь доступ к файлам. Однако казалось, что ему требуется более высокий уровень разрешений, прежде чем он сможет открыть какой-либо файл. Я протестировал это с помощью метода WindowsIdentity.Impersonate, предоставив полные разрешения на вызов метода MediaPlayer.Open, но изменений не произошло.

Наконец, я попытался передать путь к аудиофайлу в локальной файловой системе методу MediaPlayer.Open и вуаля, все снова заработало, как прежде! Возможно, вам следует попробовать этот последний шаг, чтобы убедиться, что ваша проблема также вызвана разрешениями безопасности.

ОБНОВЛЕНИЕ >>

Да, это оказалось ошибкой разрешений. ИТ-отдел перепутал мои права доступа, поэтому MediaPlayer (или приложение, унаследовавшее мои права доступа) не смогло открыть аудиофайл. После предоставления мне правильных прав MediaPlayer снова заработал нормально.

Я надеюсь, что это помогает.

person Sheridan    schedule 19.02.2013