Как видно из названия, у меня есть пользовательский слайдер, объявленный так:
<customControls:ThumbDragSlider IsEnabled="{Binding PlayerSourceState}"
Style="{StaticResource {x:Type Slider}}"
Value="{Binding CurrentMediaPlayer.MediaElement.Position, Mode=TwoWay, Converter={converters:SecondsToTimeSpanConverter}}"/>
Есть еще пара свойств, которые устанавливаются, больше событий и привязка некоторых команд, но я их опустил, потому что я сузил проблему производительности до этой конкретной строки:
Value="{Binding CurrentMediaPlayer.MediaElement.Position, Mode=TwoWay, Converter={converters:SecondsToTimeSpanConverter}}"
Удаление также удаляет все лаги. На моем ПК он работает нормально, но при тестировании на старой машине без графического процессора, используя только процессор как таковой, он не работает хорошо. Этот ползунок используется для навигации по MediaElement
, и задержка наиболее распространена в реальном медиа-файле, он даже закрывается.
Преобразователь объявляется следующим образом:
[ValueConversion(typeof(double), typeof(TimeSpan))]
public class SecondsToTimeSpanConverter : BaseConverter, IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (value is TimeSpan ts)
{
return ts;
}
return TimeSpan.FromSeconds((double)value);
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return TimeSpan.FromSeconds((double)value);
}
}
И пользовательский слайдер вот так:
public class ThumbDragSlider : Slider
{
public event DragStartedEventHandler DragStarted;
public event DragCompletedEventHandler DragCompleted;
public event EventHandler<MouseEventArgs> ThumbMouseEnter;
public new TimeSpan Value
{
get => TimeSpan.FromSeconds(base.Value);
set => base.Value = value.TotalSeconds;
}
public ThumbDragSlider()
{
Loaded += OnLoaded;
}
private void OnLoaded(object sender, System.Windows.RoutedEventArgs e)
{
Loaded -= OnLoaded;
var track = this.GetElementFromTemplate<Track>("PART_Track");
track.Thumb.MouseEnter += (o, args) => ThumbMouseEnter?.Invoke(o, args);
}
protected override void OnThumbDragStarted(DragStartedEventArgs e)
{
base.OnThumbDragStarted(e);
DragStarted?.Invoke(this, e);
}
protected override void OnThumbDragCompleted(DragCompletedEventArgs e)
{
base.OnThumbDragCompleted(e);
DragCompleted?.Invoke(this, e);
}
}
Каждые 250 мсек происходит событие таймера для синхронизации значения ползунка со значением MediaElement
, привязка не может этого сделать, потому что MediaElement
не имеет DependencyProperty
, отвечающего за Position
, и нет INotifyPropertyChanged
событие, которое запускается.
Обработчик событий System.Timers.Timer:
Application.Current.Dispatcher.Invoke(() => sMovieSkipSlider.Value =
ViewModel.CurrentMediaPlayer.MediaElement.Position);
Что может быть причиной проблемы и как я могу ее исправить?