Commit 763f17cb authored by Stéphane Mitermite's avatar Stéphane Mitermite Committed by Martin Finkel

Fix and improve WPF control

- Corrects design mode
- Removes unnecessary things
- Adds the possibility to update the content after control loading
- Make a true themable control
- Corrects padding

(cherry picked from commit 391b7dc4b3e9481b34ee78e0ca6484852ac39211)
parent ad272f5f
......@@ -8,6 +8,6 @@
mc:Ignorable="d"
Title="Example1" Height="450" Width="800">
<Grid>
<uc:VideoView x:Name="Player" Panel.ZIndex="1" />
<uc:VideoView x:Name="Player" />
</Grid>
</Window>
\ No newline at end of file
using System;
using LibVLCSharp.Shared;
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using LibVLCSharp.Shared;
namespace LibVLCSharp.WPF
{
internal partial class ForegroundWindow : Window
{
Window _wndhost;
readonly ContentControl _bckgnd;
readonly FrameworkElement _bckgnd;
UIElement _content;
readonly Point _zeroPoint = new Point(0, 0);
......@@ -20,15 +18,15 @@ namespace LibVLCSharp.WPF
set
{
_content = value;
PART_Content.Children.Clear();
if (_content != null)
{
PART_Content.Children.Clear();
PART_Content.Children.Add(_content);
}
}
}
internal ForegroundWindow(ContentControl background)
internal ForegroundWindow(FrameworkElement background)
{
InitializeComponent();
......
......@@ -12,4 +12,7 @@
<Reference Include="WindowsFormsIntegration" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Page Include="Themes\Generic.xaml" />
</ItemGroup>
</Project>
\ No newline at end of file
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None,
ResourceDictionaryLocation.SourceAssembly
)]
......@@ -4,18 +4,21 @@
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:local="clr-namespace:LibVLCSharp.WPF">
<Style x:Key="VideoViewStyle" TargetType="{x:Type local:VideoView}">
<Style TargetType="{x:Type local:VideoView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:VideoView}">
<Grid >
<DockPanel LastChildFill="true">
<WindowsFormsHost HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="PART_PlayerHost">
<wf:Panel Dock="Fill" x:Name="PART_PlayerView" />
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Margin="{TemplateBinding Padding}">
<Grid>
<WindowsFormsHost x:Name="PART_PlayerHost">
<wf:Panel x:Name="PART_PlayerView" />
</WindowsFormsHost>
</DockPanel>
<ContentControl Content="{TemplateBinding Content}" />
</Grid>
<ContentPresenter Content="{TemplateBinding Content}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
......
using System;
using LibVLCSharp.Shared;
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using LibVLCSharp.Shared;
using System.Windows.Forms.Integration;
namespace LibVLCSharp.WPF
{
public class VideoView : UserControl, IVideoView, IDisposable
[TemplatePart(Name = PART_PlayerHost, Type = typeof(WindowsFormsHost))]
[TemplatePart(Name = PART_PlayerView, Type = typeof(System.Windows.Forms.Panel))]
public class VideoView : ContentControl, IVideoView, IDisposable
{
double _controlWidth;
double _controlHeight;
readonly ForegroundWindow _foreground;
private const string PART_PlayerHost = "PART_PlayerHost";
private const string PART_PlayerView = "PART_PlayerView";
public VideoView()
{
var res = Application.LoadComponent(new Uri("/LibVLCSharp.WPF;component/Styles/VideoView.xaml", UriKind.RelativeOrAbsolute)) as ResourceDictionary;
Style = res["VideoViewStyle"] as Style;
DefaultStyleKey = typeof(VideoView);
_foreground = new ForegroundWindow(this);
if (!IsDesignMode)
{
Core.Initialize();
Core.Initialize();
LibVLC = new LibVLC();
MediaPlayer = new MediaPlayer(LibVLC);
LibVLC = new LibVLC();
MediaPlayer = new MediaPlayer(LibVLC);
Unloaded += VideoView_Unloaded;
}
}
SizeChanged += OnSizeChanged;
~VideoView()
{
Dispose();
}
_controlHeight = Height;
_controlWidth = Width;
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; }
Loaded += VideoView_Loaded;
Unloaded += VideoView_Unloaded;
}
public MediaPlayer MediaPlayer { get; private set; }
public LibVLC LibVLC { get; private set; }
void VideoView_Unloaded(object sender, RoutedEventArgs e)
private void VideoView_Unloaded(object sender, RoutedEventArgs e)
{
Dispose();
}
void VideoView_Loaded(object sender, RoutedEventArgs e)
public override void OnApplyTemplate()
{
MediaPlayer.Hwnd = ((System.Windows.Forms.Panel)Template.FindName("PART_PlayerView", this)).Handle;
base.OnApplyTemplate();
if (Content != null)
if (!IsDesignMode)
{
var content = Content;
Content = null;
_foreground.Content = (UIElement)content;
var windowsFormsHost = Template.FindName(PART_PlayerHost, this) as FrameworkElement;
if (windowsFormsHost != null)
{
ForegroundWindow = new ForegroundWindow(windowsFormsHost);
ForegroundWindow.Content = ViewContent;
}
var hwnd = (Template.FindName(PART_PlayerView, this) as System.Windows.Forms.Panel)?.Handle;
if (hwnd != null)
{
MediaPlayer.Hwnd = (IntPtr)hwnd;
}
}
}
void VLCResize()
protected override void OnContentChanged(object oldContent, object newContent)
{
uint h = 0, w = 0;
base.OnContentChanged(oldContent, newContent);
if (MediaPlayer.Size(0, ref w, ref h))
if (IsDesignMode || IsUpdatingContent)
{
var scalew = (float)_controlWidth / w;
var scaleh = (float)_controlHeight / h;
var scale = scalew < scaleh ? scalew : scaleh;
MediaPlayer.Scale = scale;
return;
}
}
void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
_controlWidth = e.NewSize.Width;
_controlHeight = e.NewSize.Height;
IsUpdatingContent = true;
try
{
Content = null;
}
finally
{
IsUpdatingContent = false;
}
if (MediaPlayer.IsPlaying)
ViewContent = newContent as UIElement;
if (ForegroundWindow != null)
{
VLCResize();
ForegroundWindow.Content = ViewContent;
}
}
public void Dispose()
{
if (MediaPlayer.IsPlaying)
MediaPlayer.Stop();
SizeChanged -= OnSizeChanged;
Loaded -= VideoView_Loaded;
Unloaded -= VideoView_Unloaded;
MediaPlayer.Hwnd = IntPtr.Zero;
MediaPlayer.Dispose();
LibVLC.Dispose();
}
if (MediaPlayer != null)
{
if (MediaPlayer.IsPlaying)
MediaPlayer.Stop();
MediaPlayer.Hwnd = IntPtr.Zero;
MediaPlayer.Dispose();
MediaPlayer = null;
}
public MediaPlayer MediaPlayer { get; }
public LibVLC LibVLC { get; }
if (LibVLC != null)
{
LibVLC.Dispose();
LibVLC = null;
}
}
}
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment