【发布时间】:2018-10-08 14:01:57
【问题描述】:
正如标题所说,我有一个这样声明的自定义滑块:
<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}}"
删除它也会消除所有滞后。在我的 PC 上它运行得很好,但是当在没有 GPU 的旧机器上测试时,只使用 CPU,它运行得不好。此滑块用于在 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 没有负责 Position 的 DependencyProperty,也没有是 INotifyPropertyChanged 正在触发的事件。
System.Timers.Timer 的事件处理器:
Application.Current.Dispatcher.Invoke(() => sMovieSkipSlider.Value =
ViewModel.CurrentMediaPlayer.MediaElement.Position);
什么可能导致问题,我该如何解决?
【问题讨论】:
-
@glenebob 删除绑定会导致问题,例如每当拖动滑块的拇指时,媒体元素都不会更新。
-
对不起,我弄错了。正如我所建议的那样,直接属性更新不会删除两种方式的绑定。
-
既然滑块值和媒体元素位置都在TimeSpan中,为什么需要转换器?
-
另外,我建议在拖动完成事件中设置媒体元素位置的值并一起删除绑定。
-
@ShivaniKatukota 查看您的第一条评论this。