I have set up a simple example to try to achieve a simple thing: exposing a dependency property in a custom control that exposes a ActualWidth/ActualHeight of a control within this custom control.
In order to attempt to achieve that I have:
customcontrol.cs
public class CustomControl : ContentControl
{
static CustomControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl)));
}
public static readonly DependencyProperty RenderedWidthProperty = DependencyProperty.Register(
"RenderedWidth", typeof (double), typeof (CustomControl), new PropertyMetadata(default(double)));
public double RenderedWidth
{
get { return (double) GetValue(RenderedWidthProperty); }
set { SetValue(RenderedWidthProperty, value); }
}
public static readonly DependencyProperty RenderedHeightProperty = DependencyProperty.Register(
"RenderedHeight", typeof (double), typeof (CustomControl), new PropertyMetadata(default(double)));
public double RenderedHeight
{
get { return (double) GetValue(RenderedHeightProperty); }
set { SetValue(RenderedHeightProperty, value); }
}
}
generic.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Custom_Control_Pushing_ActualWidth">
<Style TargetType="{x:Type local:CustomControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl}">
<Grid local:SizeObserver.Observe="True"
local:SizeObserver.ObservedWidth="{Binding RenderedWidth, RelativeSource={RelativeSource TemplatedParent}}"
local:SizeObserver.ObservedHeight="{Binding RenderedHeight, RelativeSource={RelativeSource TemplatedParent}}">
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
viewmodel.cs
class ViewModel
{
private double width;
private double height;
public double Width
{
get { return width; }
set
{
width = value;
Console.WriteLine("Width: {0}", value);
}
}
public double Height
{
get { return height; }
set
{
height = value;
Console.WriteLine("Height: {0}", value);
}
}
}
mainwindow.xaml
<Window x:Class="Custom_Control_Pushing_ActualWidth.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Custom_Control_Pushing_ActualWidth"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<Grid>
<local:CustomControl RenderedWidth="{Binding Width, Mode=OneWayToSource}" RenderedHeight="{Binding Height, Mode=OneWayToSource}" />
</Grid>
</Window>
And I use SizeObserver from this SO answer.
However although I see the code in the dependency property being updated in the size observer, the bound viewmodel property's setter doesn't get set with the values. Something's wrong with my binding and I don't know what it is.
How can I correctly bind the DependencyProperty with the ViewModel's property?