Skip to content

Instantly share code, notes, and snippets.

@sandrock
Created April 11, 2013 14:37
Show Gist options
  • Save sandrock/5363885 to your computer and use it in GitHub Desktop.
Save sandrock/5363885 to your computer and use it in GitHub Desktop.
Helps resize a control to fill its parent. Works only with a Image control but may be enhanced to work with other controls. Works in Windows Phone, may work in Silverlight/WPF. See http://stackoverflow.com/questions/13535022/windows-8-image-uniformfill-centered
namespace MyPhoneApp.Behaviors
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Media;
using System.Windows.Media.Imaging;
/// <summary>
/// Helps resize a control to fill its parent.
/// Provides a Stretch=UniformToFill behavior.
/// </summary>
public class FillParentBehavior : Behavior<FrameworkElement>
{
/// <summary>
/// The parent element to measure.
/// </summary>
private FrameworkElement parent;
/// <summary>
/// Called after the behavior is attached to an AssociatedObject.
/// </summary>
/// <remarks>
/// Override this to hook up functionality to the AssociatedObject.
/// </remarks>
protected override void OnAttached()
{
base.OnAttached();
this.parent = VisualTreeHelper.GetParent(this.AssociatedObject) as FrameworkElement;
if (this.parent != null)
{
this.parent.SizeChanged += this.OnParentSizeChanged;
this.OnParentSizeChanged(null, null);
}
}
/// <summary>
/// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.
/// </summary>
/// <remarks>
/// Override this to unhook functionality from the AssociatedObject.
/// </remarks>
protected override void OnDetaching()
{
base.OnDetaching();
if (this.parent != null)
{
this.parent.SizeChanged -= this.OnParentSizeChanged;
}
}
/// <summary>
/// Called when [parent size changed].
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="SizeChangedEventArgs"/> instance containing the event data.</param>
private void OnParentSizeChanged(object sender, SizeChangedEventArgs e)
{
double width = this.AssociatedObject.Width;
double height = this.AssociatedObject.Height;
var parentSize = new Size(this.parent.ActualWidth, this.parent.ActualHeight);
var parentRatio = parentSize.Width / parentSize.Height;
// determine optimal size
if (this.AssociatedObject is Image)
{
var image = (Image)this.AssociatedObject;
if (image.Source is BitmapImage)
{
var bitmap = (BitmapImage)image.Source;
var imageSize = new Size(bitmap.PixelWidth, bitmap.PixelHeight);
var imageRatio = imageSize.Width / imageSize.Height;
if (parentRatio <= imageRatio)
{
// picture has a greater width than necessary
// use its height
width = double.NaN;
height = parentSize.Height;
}
else
{
// picture has a greater height than necessary
// use its width
width = parentSize.Width;
height = double.NaN;
}
}
}
this.AssociatedObject.Width = width;
this.AssociatedObject.Height = height;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment