show .gif animation; solve a memory leak caused by background UI thread

This commit is contained in:
Paddy Xu
2017-05-01 13:30:43 +03:00
parent bb8e4b03c8
commit 71f02c88b3
8 changed files with 47 additions and 21 deletions

View File

@@ -5,6 +5,7 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using XamlAnimatedGif;
namespace QuickLook.Plugin.ImageViewer
{
@@ -21,6 +22,18 @@ namespace QuickLook.Plugin.ImageViewer
{
InitializeComponent();
LoadImage(path);
Loaded += (sender, e) => { ZoomToFit(); };
viewPanel.PreviewMouseWheel += ViewPanel_PreviewMouseWheel;
viewPanel.PreviewMouseLeftButtonDown += ViewPanel_PreviewMouseLeftButtonDown;
viewPanel.PreviewMouseMove += ViewPanel_PreviewMouseMove;
}
private void LoadImage(string path)
{
var ori = ImageFileHelper.GetOrientationFromExif(path);
var bitmap = new BitmapImage();
@@ -36,14 +49,11 @@ namespace QuickLook.Plugin.ImageViewer
: Rotation.Rotate0;
bitmap.EndInit();
}
viewPanelImage.Source = bitmap;
Loaded += (sender, e) => { ZoomToFit(); };
viewPanel.PreviewMouseWheel += ViewPanel_PreviewMouseWheel;
viewPanel.PreviewMouseLeftButtonDown += ViewPanel_PreviewMouseLeftButtonDown;
viewPanel.PreviewMouseMove += ViewPanel_PreviewMouseMove;
if (Path.GetExtension(path).ToLower() == ".gif")
AnimationBehavior.SetSourceUri(viewPanelImage, new Uri(path));
}
private void ViewPanel_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

View File

@@ -44,8 +44,8 @@
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
<Reference Include="WpfAnimatedGif, Version=1.4.14.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\WpfAnimatedGif.1.4.14\lib\net\WpfAnimatedGif.dll</HintPath>
<Reference Include="XamlAnimatedGif, Version=1.1.9.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\XamlAnimatedGif.1.1.9\lib\net45\XamlAnimatedGif.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="WpfAnimatedGif" version="1.4.14" targetFramework="net452" />
<package id="XamlAnimatedGif" version="1.1.9" targetFramework="net452" />
</packages>

View File

@@ -15,7 +15,8 @@ namespace QuickLook
protected override void OnStartup(StartupEventArgs e)
{
AppDomain.CurrentDomain.UnhandledException +=
(sender, args) => MessageBox.Show(((Exception) args.ExceptionObject).Message);
(sender, args) => MessageBox.Show(((Exception) args.ExceptionObject).Message + Environment.NewLine +
((Exception) args.ExceptionObject).StackTrace);
base.OnStartup(e);
}

View File

@@ -32,8 +32,8 @@ namespace QuickLook.Controls
private void CreateContentHelper()
{
_threadedHelper = new ThreadedVisualHelper(CreateContent, SafeInvalidateMeasure);
_hostVisual = _threadedHelper.HostVisual;
ThreadedHelper = new ThreadedVisualHelper(CreateContent, SafeInvalidateMeasure);
_hostVisual = ThreadedHelper.HostVisual;
}
private void SafeInvalidateMeasure()
@@ -43,23 +43,23 @@ namespace QuickLook.Controls
private void HideContentHelper()
{
if (_threadedHelper != null)
if (ThreadedHelper != null)
{
_threadedHelper.Exit();
_threadedHelper = null;
ThreadedHelper.Exit();
ThreadedHelper = null;
InvalidateMeasure();
}
}
protected override Size MeasureOverride(Size availableSize)
{
if (_threadedHelper != null)
return _threadedHelper.DesiredSize;
if (ThreadedHelper != null)
return ThreadedHelper.DesiredSize;
return base.MeasureOverride(availableSize);
}
private class ThreadedVisualHelper
public class ThreadedVisualHelper
{
private readonly CreateContentFunction _createContent;
private readonly Action _invalidateMeasure;
@@ -109,7 +109,7 @@ namespace QuickLook.Controls
#region Private Fields
private ThreadedVisualHelper _threadedHelper;
public ThreadedVisualHelper ThreadedHelper;
private HostVisual _hostVisual;
#endregion

View File

@@ -8,7 +8,7 @@ using System.Windows.Media;
namespace QuickLook.Controls
{
[StyleTypedProperty(Property = "BusyStyle", StyleTargetType = typeof(Control))]
public class BusyDecorator : Decorator
public class BusyDecorator : Decorator, IDisposable
{
private readonly BackgroundVisualHost _busyHost = new BackgroundVisualHost();
@@ -42,6 +42,13 @@ namespace QuickLook.Controls
}
}
public void Dispose()
{
GC.SuppressFinalize(this);
_busyHost.ThreadedHelper.Exit();
}
protected override Visual GetVisualChild(int index)
{
if (Child != null)
@@ -97,6 +104,11 @@ namespace QuickLook.Controls
Math.Max(ret.Height, _busyHost.RenderSize.Height));
}
~BusyDecorator()
{
Dispose();
}
#region IsBusyIndicatorShowing Property
/// <summary>

View File

@@ -78,7 +78,7 @@
</Style.Triggers>
</Style>
</Grid.Style>
<control:BusyDecorator IsBusyIndicatorShowing="True" VerticalAlignment="Center"
<control:BusyDecorator x:Name="busyDecorator" IsBusyIndicatorShowing="True" VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Grid>
</Grid>

View File

@@ -41,6 +41,9 @@ namespace QuickLook
GC.SuppressFinalize(this);
ContextObject?.Dispose();
// stop the background thread
busyDecorator?.Dispose();
}
private void DragMoveCurrentWindow(object sender, MouseButtonEventArgs e)