/// <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"));
}
}
}