// this is where the magic happens private void Thumbnail_LayoutUpdated(object sender, EventArgs e) { if (IntPtr.Zero == thumb) { InitialiseThumbnail(this.Source); } if (IntPtr.Zero != thumb) { if (!target.RootVisual.IsAncestorOf(this)) { //we are no longer in the visual tree ReleaseThumbnail(); return; } DwmQueryThumbnailSourceSize(this.thumb, out WPF.SysSize size); Rect visib = WPF.GetVisibleArea(this); ThumbnailProperties props = new ThumbnailProperties(); if (visib == Rect.Empty) { props.Visible = false; props.Flags = ThumbnailFlags.Visible; } else { double ratioSrc = (double)size.Width / (double)size.Height; double ratioDest = visib.Width / visib.Height; // Center the thumbnail in the visible area double newSize; if (ratioSrc > ratioDest) { newSize = visib.Height * ratioDest / ratioSrc; visib.Y += (visib.Height - newSize) / 2.0; visib.Height = newSize; } else { newSize = visib.Width * ratioSrc / ratioDest; visib.X += (visib.Width - newSize) / 2.0; visib.Width = newSize; } // Translate to screen pixels Point a = target.RootVisual.PointToScreen(visib.TopLeft); Point b = target.RootVisual.PointToScreen(visib.BottomRight); Point w = Application.Current.MainWindow.PointToScreen(new Point(0, 0)); props.Destination = new WPF.SysRect( (int)Math.Ceiling(a.X - w.X), (int)Math.Ceiling(a.Y - w.Y), (int)Math.Ceiling(b.X - w.X), (int)Math.Ceiling(b.Y - w.Y)); props.Visible = this.Visibility == Visibility.Visible; props.Flags = ThumbnailFlags.Visible | ThumbnailFlags.RectDestination; } DwmUpdateThumbnailProperties(thumb, ref props); } }