If anyone's interested, here's how I've done in in a behaviour.
I pass on Height
or Width
according to the property I want bound.
Here's the class:
public static class DynamicControlResizeBehavior
{
public static readonly DependencyProperty TargetProperty =
DependencyProperty.RegisterAttached("Target", typeof(FrameworkElement), typeof(DynamicControlResizeBehavior), new PropertyMetadata(OnTargetSetCallback));
public static readonly DependencyProperty PropertyNameProperty =
DependencyProperty.RegisterAttached("PropertyName", typeof(string), typeof(DynamicControlResizeBehavior), new PropertyMetadata(OnPropertyNameSetCallback));
public static string GetPropertyName(DependencyObject obj)
{
return (string)obj.GetValue(PropertyNameProperty);
}
public static void SetPropertyName(DependencyObject obj, string value)
{
obj.SetValue(PropertyNameProperty, value);
}
public static FrameworkElement GetTarget(DependencyObject obj)
{
return (FrameworkElement)obj.GetValue(TargetProperty);
}
public static void SetTarget(DependencyObject obj, FrameworkElement value)
{
obj.SetValue(TargetProperty, value);
}
private static void SynchronizeProperty(DependencyObject dependencyObject)
{
var target = GetTarget(dependencyObject);
if (target != null)
{
var propertyName = GetPropertyName(dependencyObject);
DependencyProperty dependencyToRead;
DependencyProperty dependencyToWrite;
if (string.Equals(propertyName, "Width", StringComparison.InvariantCulture))
{
dependencyToRead = FrameworkElement.ActualWidthProperty;
dependencyToWrite = FrameworkElement.WidthProperty;
}
else if (string.Equals(propertyName, "Height", StringComparison.InvariantCulture))
{
dependencyToRead = FrameworkElement.ActualHeightProperty;
dependencyToWrite = FrameworkElement.HeightProperty;
}
else
{
return;
}
var propertySize = (double)target.GetValue(dependencyToRead);
dependencyObject.SetValue(dependencyToWrite, propertySize);
}
}
private static void OnTargetSetCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var oldElement = e.OldValue as FrameworkElement;
if (oldElement != null)
{
oldElement.SizeChanged -= (o, s) => SynchronizeProperty(d);
}
var newElement = e.NewValue as FrameworkElement;
if (newElement != null)
{
newElement.SizeChanged += (o, s) => SynchronizeProperty(d);
}
}
private static void OnPropertyNameSetCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SynchronizeProperty(d);
}
}
And here's how it's used:
<TextBlock
Behaviors:DynamicControlResizeBehavior.Target="{Binding ElementName=submitButton}"
Behaviors:DynamicControlResizeBehavior.PropertyName="Width"
HorizontalAlignment="Right"
Margin="5,20,5,5"
TextWrapping="Wrap"
Text="{Binding Path=Resource.RequestDemoLoginText, Source={StaticResource LocalizedStrings }}"
/>
<Button
x:Name="submitButton"
Margin="5"
Height="Auto"
Width="Auto"
HorizontalAlignment="Right"
HorizontalContentAlignment="Left"
Content="{Binding Path=Resource.RequestDemoLogin, Source={StaticResource LocalizedStrings }}" />
Hope that might help someone else.