Wednesday, 20 November 2013

ActualSizeProxy

/// <summary>
/// Allows binding to a container (or other framework element) height or width
///
/// Example:
///     <UserControl.Resources>
///          <utils:ActualSizePropertyProxy Element="{Binding ElementName=SellPanel}"  x:Name="SellPanelSizeProxy"/>
///     </UserControl.Resources>    
///
///     <TextBlock Width="{Binding ElementName=SellPanelSizeProxy, Path=ActualWidthValue}" />
///
/// </summary>
public class ActualSizePropertyProxy : FrameworkElement, INotifyPropertyChanged
{
    public static readonly DependencyProperty ElementProperty = DependencyProperty.Register(
        "Element",
        typeof(FrameworkElement),
        typeof(ActualSizePropertyProxy),
        new PropertyMetadata(null, OnElementPropertyChanged));
    public event PropertyChangedEventHandler PropertyChanged;
    public FrameworkElement Element
    {
        get { return (FrameworkElement)this.GetValue(ElementProperty); }
        set { this.SetValue(ElementProperty, value); }
    }
    public double ActualHeightValue
    {
        get { return this.Element == null ? 0 : this.Element.ActualHeight; }
    }
    public double ActualWidthValue
    {
        get { return this.Element == null ? 0 : this.Element.ActualWidth; }
    }
    private static void OnElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((ActualSizePropertyProxy)d).OnElementChanged(e);
    }
    private void OnElementChanged(DependencyPropertyChangedEventArgs e)
    {
        var oldElement = (FrameworkElement)e.OldValue;
        var newElement = (FrameworkElement)e.NewValue;
        newElement.SizeChanged += this.ElementSizeChanged;
        if (oldElement != null)
        {
            oldElement.SizeChanged -= this.ElementSizeChanged;
        }
        this.NotifyPropChange();
    }
    private void ElementSizeChanged(object sender, SizeChangedEventArgs e)
    {
        this.NotifyPropChange();
    }
    private void NotifyPropChange()
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs("ActualWidthValue"));
            this.PropertyChanged(this, new PropertyChangedEventArgs("ActualHeightValue"));
        }
    }
}

No comments:

Post a Comment