如何设置由第三方计时器更新的DependencyProperty



我在玩Vlc。DotNet库(Nuget:Vlc.DotNet/https://github.com/ZeBobo5/Vlc.DotNet)。它实际上是一个围绕libvlc.dll的WinForms包装器,具有WPF控件的非常的粗略实现,该控件仅将WinForms控件包装在HwndHost:中

//WPF control class
public class VlcControl : HwndHost 
{
//The WPF control has a property called MediaPlayer,
//which is an instance of Forms.VlcControl
public Forms.VlcControl MediaPlayer { get; private set; }
//WPF control constructor
public VlcControl()
{
MediaPlayer = new Forms.VlcControl();
}
//BuildWindowCore and DestroyWindowCore methods omitted for brevity
}

这意味着,如果我想绑定任何东西,我需要跳过一些关卡。如果我的WPF控件实例名为MyWpfControl,那么我需要通过MyWpfVlcControl来解决所有问题。MediaPlayer。[SomeMethod/SomeProperty]。我想向WPF控件添加一些DependencyProperty,以使绑定更容易。我遇到了在计时器上更新的属性的问题,这些属性是由后台dll和用户通过WPF控件设置的。

WinForms播放器的Time属性类型为long,以毫秒为单位指示所用的媒体时间。它还有一个名为TimeChanged的事件,它在播放过程中不断触发,更新所用的媒体时间。

我为TimeChanged事件在WPF控件中添加了一个事件处理程序:

//WPF control constructor
public VlcControl()
{
MediaPlayer = new Forms.VlcControl();
MediaPlayer.TimeChanged += OnTimeChangedInternal;
}
private void OnTimeChangedInternal(object sender, VlcMediaPlayerTimeChangedEventArgs e)
{
Time = e.NewTime;
}

如果我在WPF控件中设置了一个DependencyProperty来包裹Time,它看起来像这样:

// Using a DependencyProperty as the backing store for Time.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty TimeProperty =
DependencyProperty.Register("Time", typeof(long), typeof(VlcControl), new FrameworkPropertyMetadata(0L, new PropertyChangedCallback(OnTimeChanged)));
/// <summary>
/// Sets and gets the Time property.
/// </summary>
public long Time
{
get
{
return (long)this.GetValue(TimeProperty);
}
set
{
this.Dispatcher.Invoke((Action)(() =>
{
this.SetValue(TimeProperty, value);
}));
}
}
private static void OnTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ 
//Tried this - bad idea!       
//MediaPlayer.Time = (long)e.NewValue;        
}  

时间从libvlc.dll->WinForms->WPF进行了漂亮的更新。很遗憾,如果我想设置MediaPlayer。WPF控件的Time属性,我需要将上面的注释行合并到OnTimeChanged中。当取消注释并且MediaPlayer更新Time属性(与WPF控件相反)时,它会进入TimeChanged->SetTime->TimeChanged-->SetTime->的无限循环。。。

有没有更好的方法来实现这一点?我可以在某个地方添加一个参数来指示时间是从WPF代码还是WinForms代码设置的吗?

您可以尝试实现一种类型的指示符来防止无限循环。类似于:

bool isUpdating = false;
private static void OnTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ 
if (!isUpdating)
{
isUpdating = true;
MediaPlayer.Time = (long)e.NewValue;
isUpdating = false;
}
}  

最新更新