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

时间:2015-04-17 19:24:43

标签: c# .net wpf

我正在玩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控件中添加一些DependencyProperties以使绑定更容易。我遇到了在计时器上更新并由后备dll设置的属性以及用户通过WPF控件设置的问题。

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

我为我的WPF控件添加了一个事件处理程序,用于TimeChanged事件:

//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精美更新 - &gt; WinForms - &gt; WPF。不幸的是,如果我想从WPF控件设置MediaPlayer.Time属性,我需要在OnTimeChanged中包含上面的注释行。当取消注释并且MediaPlayer更新Time属性(而不是WPF控件)时,它会自动进入TimeChanged的无限循环 - &gt; SetTime - &gt; TimeChanged - &gt; SetTime - &gt; ......

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

1 个答案:

答案 0 :(得分:1)

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

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