using System.Windows.Controls; using System.Windows; using System.Windows.Media; using System.Windows.Markup; namespace Minesweeper { [ContentProperty("Child")] public class Viewbox: Control { public static DependencyProperty ChildProperty = DependencyProperty.Register("Child", typeof(FrameworkElement), typeof(Viewbox), Viewbox.ChildChanged); private Panel childHost; private ScaleTransform scale; private TranslateTransform offset; public Viewbox() { // Inlining the template to make the file standalone. // It's not intended to be retemplated. string templateXaml = @" "; this.Template = (ControlTemplate)XamlReader.Load(templateXaml); } public FrameworkElement Child { get { return (FrameworkElement)this.GetValue(Viewbox.ChildProperty); } set { this.SetValue(Viewbox.ChildProperty, value); } } private static void ChildChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((Viewbox)sender).OnChildChanged(e); } protected virtual void OnChildChanged(DependencyPropertyChangedEventArgs e) { if (e.OldValue != null && this.childHost != null) this.childHost.Children.Remove((FrameworkElement)e.OldValue); if (e.NewValue != null && this.childHost != null) this.childHost.Children.Add((FrameworkElement)e.NewValue); } protected override Size ArrangeOverride(Size finalSize) { double scaleX = finalSize.Width / this.Child.DesiredSize.Width; double scaleY = finalSize.Height / this.Child.DesiredSize.Height; if (scaleX > scaleY) { this.scale.ScaleX = this.scale.ScaleY = scaleY; this.offset.X = (finalSize.Width - this.Child.DesiredSize.Width * scaleY) / 2; this.offset.Y = 0; } else { this.scale.ScaleX = this.scale.ScaleY = scaleX; this.offset.Y = (finalSize.Height - this.Child.DesiredSize.Height * scaleX) / 2; //this.offset.X = 0; } this.Child.Arrange(new Rect(0, 0, this.Child.DesiredSize.Width, this.Child.DesiredSize.Height)); return finalSize; } protected override void OnApplyTemplate() { base.OnApplyTemplate(); this.childHost = this.GetTemplateChild("ELEMENT_ChildHost") as Panel; this.scale = new ScaleTransform(); this.offset = new TranslateTransform(); TransformGroup transform = new TransformGroup(); transform.Children.Add(this.scale); transform.Children.Add(this.offset); this.childHost.RenderTransform = transform; if (this.Child != null) this.childHost.Children.Add(this.Child); } } }