2015-04-17 27 views
1

我在玩Vlc.DotNet庫(Nuget:Vlc.Dotnet/https://github.com/ZeBobo5/Vlc.DotNet)。它有效地圍繞libvlc.dll一個WinForms包裝,具有非常粗略實現WPF控件的這只是包裝在一個HwndHost的的WinForms控制:如何設置由第三方定時器更新的DependencyProperty?

//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]來解決所有問題。我想添加一些DependencyProperties到WPF控件,使綁定更容易。我遇到了在定時器上更新的屬性問題,並且由後臺dll和用戶通過WPF控件設置。

WinForms播放器具有long類型的Time屬性,表示媒體時間以毫秒爲單位。它還有一個名爲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; 
} 

如果我成立了一個DependencyProperty在我的WPF控件周圍包裹時,它看起來是這樣的:

// 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更新很漂亮。不幸的是,如果我想從WPF控件設置MediaPlayer.Time屬性,我需要在OnTimeChanged中包含上面的註釋行。如果取消註釋並且MediaPlayer更新了Time屬性(而不是WPF控件),它會自動進入TimeChanged - > SetTime - > TimeChanged - > SetTime - >的無限循環...

是否有更好的這種方式來實現?我可以在某處添加一個參數來指示是否從WPF或WinForms代碼設置時間?

+0

只是爲了清除一些事情VlcControl和Forms.VlcControl是不同的類,對吧?使得閱讀什麼是很難的。 –

+0

是的,VlcControl和Forms.VlcControl是不同的類。我會一遍一遍地回答這個問題,看看我能否清理一些問題。 – goobering

回答

1

您可能會嘗試實施一種指示器來防止無限循環。就像:

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

儘管我認爲這會給你一個回合。我最初也會考慮同樣的事情。 –

+0

這就是我剛剛完成的。我不得不聲明我的指示符字段爲靜態,以使其進入靜態OnTimeChanged方法的範圍。 – goobering

+0

在'OnTimeChanged'中,您有引發該方法的對象(在上面的代碼中稱爲'd')。所以你可以將它轉換爲'VlcControl'並在控件上使用公共屬性而不是靜態標誌。 –

相關問題