MediaElement - Merkwürdiges Problem

  • WPF

Es gibt 49 Antworten in diesem Thema. Der letzte Beitrag () ist von KaskadekingDE.

    MediaElement - Merkwürdiges Problem

    Hey zusammen :) ,

    ich habe heute ein ziemlich merkwürdiges Problem. Und zwar wollte ich per Slider die Position des MediaElements verändern. Benutzen tue ich folgenden Code:

    C#-Quellcode

    1. private void SliderMovePosition_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    2. {
    3. var slideValue = (int) SliderMovePosition.Value;
    4. var slideTimeSpan = new TimeSpan(0, 0, 0, 0, slideTimeSpan);
    5. MedElement.Position = slideTimeSpan;
    6. MedElement.Play();
    7. }


    Das Maxium ist wie folgt festgelegt: SliderMovePosition.Maximum = (int) _soundSource.GetLength().TotalSeconds;
    _soundSource ist deklariert als IWaveSource (von CSCore)

    Jedoch restartet das MediaElement immer wieder statt von der angegebenen Position abzuspielen.

    Was ist hier der Fehler?
    MfG, KaskadekingDE :)
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Den Code hab ich von MSDN :whistling:

    msdn.microsoft.com/de-de/libra…t.position(v=vs.110).aspx

    VB.NET-Quellcode

    1. Dim SliderValue As Integer = CType(timelineSlider.Value, Integer)
    2. ' Overloaded constructor takes the arguments days, hours, minutes, seconds, miniseconds.
    3. ' Create a TimeSpan with miliseconds equal to the slider value.
    4. Dim ts As New TimeSpan(0, 0, 0, 0, SliderValue)
    5. myMediaElement.Position = ts


    EDIT: Hab grad gemerkt, ich muss die Sekunden festlegen nicht die Millisekunden :S
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Hab jetzt schon ein bisschen probiert. Leider wird beim Slider bei Path angezeigt: Cannot resolve property 'MedElement' in data context of type 'System.Windows.Controls.MediaElement'

    Mein Converter:
    Spoiler anzeigen

    C#-Quellcode

    1. public class MsToTimespanConverter : IValueConverter
    2. {
    3. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    4. {
    5. var timeSpan = new TimeSpan(0, 0, 0, 0, (int)value);
    6. return timeSpan;
    7. }
    8. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    9. {
    10. var timeSpan = (TimeSpan)value;
    11. return timeSpan.TotalMilliseconds;
    12. }
    13. }


    XAML:
    Spoiler anzeigen

    XML-Quellcode

    1. <controls:MetroWindow
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
    4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    5. x:Name="FrmMain" x:Class="xxx.MainWindow"
    6. xmlns:converter="clr-namespace:xxx"
    7. Title="xxx" Height="464.821" Width="906.254" ResizeMode="CanResizeWithGrip"
    8. Icon="Wwalczyszyn-Android-Style-Music-Player.ico">
    9. <controls:MetroWindow.Resources>
    10. <converter:MsToTimespanConverter x:Key="TimespanConverter"></converter:MsToTimespanConverter>
    11. </controls:MetroWindow.Resources>
    12. //...
    13. <MediaElement x:Name="MedElement" LoadedBehavior="Manual" Position="{Binding ElementName=SliderMovePosition, Converter={StaticResource TimespanConverter}}" UnloadedBehavior="Stop" ScrubbingEnabled="True"/>
    14. <Slider Name="SliderMovePosition" Value="0" Minimum="0" Maximum="{Binding ElementName=MedElement, Path=MedElement.NaturalDuration.TimeSpan.TotalMilliseconds}" Background="White"></Slider>

    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Gebunden wird an Properties im DataContext, also (hoffentlich) deinem ViewModel, nicht an Properties anderer Controls. Leg in deinem ViewModel eine neue Propertie vom Typ Timespan an, implementiere INotifyPropertyChanged korrekt dafür und binde dann das MediaElement und die TrackBar mit Mode=TwoWay daran.
    Ok, ich seh schon dass das hier sehr lange dauern wird ;(
    Aber danke das du mir hilfst :thumbsup:
    So hier: (Wahrscheinlich nicht, oder?)

    C#-Quellcode

    1. public class MainViewModel : INotifyPropertyChanged
    2. {
    3. private TimeSpan _position;
    4. public event PropertyChangedEventHandler PropertyChanged;
    5. private void OnPropertyChanged(string propertyName)
    6. {
    7. if (PropertyChanged != null)
    8. {
    9. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    10. }
    11. }
    12. public TimeSpan ElementPosition
    13. {
    14. get { return _position; }
    15. set
    16. {
    17. _position = value;
    18. OnPropertyChanged("ElementPosition");
    19. }
    20. }
    21. }


    Und wie binde ich das (wenn ichs dann richtig habe) dann an das MediaElement & den Slider an? Versteht ich nicht so ganz :S
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Das ist soweit richtig, du solltest dein ViewModell aber noch als Singletone implementieren, etwa so:

    C#-Quellcode

    1. class MainViewModel
    2. {
    3. static MainViewModel instance;
    4. public static MainViewModel Instance
    5. {
    6. get { return instance ?? (instance = new MainViewModel()); }
    7. }
    8. private MainViewModel()
    9. { }
    10. }


    Dann musst du das ViewModel als DataContext für das Window festlegen (damit wird dann automatisch der DataContext für alle Controls gesetzt):

    XML-Quellcode

    1. DataContext="{x:Static local:MainViewModel.Instance}"

    local ist der Namespace deiner Anwendung, in dem sich u.a. das ViewModel befindet.

    Wenn du jetzt Bindings setzt wird dir der Editor die Properties des ViewModels als Path anbieten.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Artentus“ ()

    Nach dem kompilieren funktionierts wieder ;)
    Dann versuch ich jetzt mal das MediaElement und den Slider zu binden

    EDIT: Achja ein kleine Frage noch :D :
    Die Propertys müssen dann in die Klasse oder darein:

    C#-Quellcode

    1. private MainViewModel()
    2. {
    3. }


    EDIT2: Hat sich erledigt :p
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „KaskadekingDE“ ()

    Also ich kann schonmal das Property zuweisen.
    Hab es jetzt so hier:

    XML-Quellcode

    1. <Slider Name="SliderMovePosition" Value="{Binding Path=ElementPosition, Mode=TwoWay}" Background="White"></Slider>


    Aber muss ich nicht das ganze noch Converten? Denn Value ist ja ein double aber ElementPosition ist ein TimeSpan.

    2. Frage:
    Wenn das so richtig ist, welcher Eigenschaft soll ich dann bei meinen MediaElement das Property zuweisen?
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯
    Den Converter hast du doch oben schonmal gesetzt, solltest doch eigentlich wissen wies geht. Einfach als Ressource verfügbar machen und dann als StaticResource dem Binding zuweisen.
    Beim Mediaelement bindest du logischerweise die Position-Eigenschaft.
    Aber Position ist keine DependencyProperty. Ich bekomm sonst beim debuggen eine XamlParseException.

    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „KaskadekingDE“ ()

    Das wusste ich nicht. In dem Fall musst du dir wohl selbst eine DependencyProperty erstellen.
    Ich hab dir einfach mal ein Beispielprojekt angehängt.
    Dateien
    Ich hab mir nun den Code einbisschen angeguckt.
    Das ganze funktioniert schon aber es gibt noch ein Problem:

    Das MediaElement ist nur dazu da den "Videoinhalt" anzuzeigen. Die "Audioausgabe" mache ich (wie oben angegeben) mit CSCore.
    Also muss ich auch die Position der Audio-Source setzen.

    Hab es schon CommandBinding gefunden aber ist dass das richtige?
    KaskadekingDE on GitHub :)
    Bitte keine Fragen über Programmierung per PN! Dafür ist das Forum hier.

    Who cares? ¯\_(ツ)_/¯