VideoView.cs 3.89 KB
Newer Older
1 2 3
using LibVLCSharp.Shared;
using System;
using System.ComponentModel;
4
using System.Diagnostics;
5 6
using System.Windows;
using System.Windows.Controls;
7
using System.Windows.Forms.Integration;
8 9 10

namespace LibVLCSharp.WPF
{
11 12 13
    [TemplatePart(Name = PART_PlayerHost, Type = typeof(WindowsFormsHost))]
    [TemplatePart(Name = PART_PlayerView, Type = typeof(System.Windows.Forms.Panel))]
    public class VideoView : ContentControl, IVideoView, IDisposable
14
    {
15 16
        private const string PART_PlayerHost = "PART_PlayerHost";
        private const string PART_PlayerView = "PART_PlayerView";
17 18 19

        public VideoView()
        {
20
            DefaultStyleKey = typeof(VideoView);
21
        }
22

23 24
        private void Attach()
        {
25 26
            if (!IsDesignMode)
            {
27 28 29 30 31
                if (MediaPlayer == null)
                {
                    Trace.Write("No MediaPlayer is set, aborting...");
                    return;
                }
32

33 34 35 36 37 38
                var hwnd = (Template.FindName(PART_PlayerView, this) as System.Windows.Forms.Panel)?.Handle;
                if (hwnd == null)
                {
                    Trace.WriteLine("HWND is NULL, aborting...");
                    return;
                }
39

40
                MediaPlayer.Hwnd = (IntPtr)hwnd;
41 42
            }
        }
43

44
        private void Detach()
45
        {
46 47 48 49 50 51 52
            if (!IsDesignMode)
            {
                if (MediaPlayer != null)
                {
                    MediaPlayer.Hwnd = IntPtr.Zero;
                }
            }
53
        }
54

55 56 57 58
        private bool IsDesignMode => (bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue;
        private ForegroundWindow ForegroundWindow { get; set; }
        private bool IsUpdatingContent { get; set; }
        private UIElement ViewContent { get; set; }
59

60 61
        private MediaPlayer _mediaPlayer;
        public MediaPlayer MediaPlayer
62
        {
63 64 65 66 67 68 69 70 71 72 73 74 75 76
            get => _mediaPlayer;
            set
            {
                if (_mediaPlayer != value)
                {
                    Detach();
                    _mediaPlayer = value;

                    if (_mediaPlayer != null)
                    {
                        Attach();
                    }
                }
            }
77 78
        }

79
        public override void OnApplyTemplate()
80
        {
81
            base.OnApplyTemplate();
82

83
            if (!IsDesignMode)
84
            {
85 86 87
                var windowsFormsHost = Template.FindName(PART_PlayerHost, this) as FrameworkElement;
                if (windowsFormsHost != null)
                {
88 89 90 91
                    ForegroundWindow = new ForegroundWindow(windowsFormsHost)
                    {
                        Content = ViewContent
                    };
92
                }
93 94 95
            }
        }

96
        protected override void OnContentChanged(object oldContent, object newContent)
97
        {
98
            base.OnContentChanged(oldContent, newContent);
99

100
            if (IsDesignMode || IsUpdatingContent)
101
            {
102
                return;
103 104
            }

105 106 107 108 109 110 111 112 113
            IsUpdatingContent = true;
            try
            {
                Content = null;
            }
            finally
            {
                IsUpdatingContent = false;
            }
114

115 116
            ViewContent = newContent as UIElement;
            if (ForegroundWindow != null)
117
            {
118
                ForegroundWindow.Content = ViewContent;
119 120 121
            }
        }

122
        #region IDisposable Support
123

124 125 126 127
        bool disposedValue;
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
128
            {
129 130 131 132
                if (disposing)
                {
                    Detach();
                }
133

134 135 136 137
                ViewContent = null;
                ForegroundWindow = null;

                disposedValue = true;
138 139
            }
        }
140 141 142 143 144 145

        public void Dispose()
        {
            Dispose(true);
        }
        #endregion
146 147
    }
}