Привязать MediaElement и значение ползунка

Я реализовал прикрепленное свойство, которое изменяет положение медиа-элемента при изменении его значения.

Присоединенное свойство определяется следующим образом:

public class MediaElementHelper
{
    public static void SetBindablePosition(UIElement element, TimeSpan value)
    {
        if (element == null)
        {
            throw new ArgumentNullException();
        }
        element.SetValue(BindablePositionProperty, value);
    }

    public static TimeSpan GetBindablePosition(UIElement element)
    {
        if (element == null)
        {
            throw new ArgumentNullException();
        }
        return (TimeSpan) element.GetValue(BindablePositionProperty);
    }

    private static void PostionPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var richEditControl = obj as MediaElement;

        if (richEditControl != null)
        {
            richEditControl.Position = (TimeSpan) e.NewValue;
        }
    }

    public static readonly DependencyProperty BindablePositionProperty =
        DependencyProperty.RegisterAttached("BindablePosition",
            typeof (TimeSpan), typeof (MediaElementHelper),
            new FrameworkPropertyMetadata(new TimeSpan(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                PostionPropertyChanged));
}

}

и в MainWindow:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_OnClick(object sender, RoutedEventArgs e)
    {
        var newFileDialog = new OpenFileDialog();
        newFileDialog.ShowDialog();
        MediaElement.Source = new Uri(newFileDialog.FileName);
    }

    private void MediaElement_OnMediaOpened(object sender, RoutedEventArgs e)
    {
        Slider.Maximum = MediaElement.NaturalDuration.TimeSpan.TotalMilliseconds;
        Slider.SmallChange = 1;
        Slider.LargeChange = 5000;
    }
}

и в xaml:

    <MediaElement Name="MediaElement"
                  Grid.Row="0"
                  loc:MediaElementHelper.BindablePosition="{Binding ElementName=Slider, Path=Value, Converter={StaticResource DoubleToTimeSpanConverter}}"
                  MediaOpened="MediaElement_OnMediaOpened" />

И мой класс преобразователя определяется следующим образом:

public class DoubleToTimeSpanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return TimeSpan.FromMilliseconds((double) value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return System.Convert.ToDouble(((TimeSpan) value).Milliseconds);
    }
}

Но когда я перетаскиваю большой палец ползунка, он работает хорошо, но когда я ничего не делаю, большой палец ползунка не двигается автоматически. Что мне нужно сделать, чтобы сделать эту привязку двухсторонней привязкой?


person AmirHossein Fathi    schedule 29.12.2014    source источник


Ответы (1)


Идеального способа не существует - в прошлом я решил это, создав новый объект DispatcherTimer, который опрашивает элемент Position и обновляет ползунок.

// this is the timer
timerVideoTime = new DispatcherTimer();
            timerVideoTime.Interval = TimeSpan.FromSeconds(1);
            timerVideoTime.Tick += new EventHandler(timer_Tick);
            timerVideoTime.Start();
        }

// the actual timer handler.
void timer_Tick(object sender, EventArgs e)
        {
            // Check if the movie finished calculate it's total time
            if (MyMediaElement.NaturalDuration.TimeSpan.TotalSeconds > 0)
            {
                if (TotalTime.TotalSeconds > 0)
                {
                    var sliderValue = MyMediaElement.Position.TotalSeconds /
                                       TotalTime.TotalSeconds;

                    if(Slider.Value != sliderValue){
                      Slider.SetCurrentValue(Slider.ValueProperty, sliderValue); 
                    }
                }
            }
person Erti-Chris Eelmaa    schedule 29.12.2014