I'm in the process of making a custom control -- specifically a pie chart. I want the markup to look something like this example:
<c:PieChart>
<!-- These dependency properties are never set -->
<c:Slice Value="{Binding RedCount}" />
<c:Slice Value="{Binding BlueCount}" />
<c:Slice Value="{Binding GreenCount}" />
</c:PieChart>
PieChart
derives from Control
:
[ContentProperty("Slices")]
public class PieChart : Control
{
public PieChart()
{
Slices = new ObservableCollection<Slice>();
}
public ObservableCollection<Slice> Slices { get; private set; }
}
The above XAML causes the Slices
property to be populated with three instances of Slice
.
Here's a snippet from Slice
:
public class Slice : ContentControl
{
public static DependencyProperty ValueProperty
= DependencyProperty.Register(
"Value", typeof(double), typeof(Slice),
new PropertyMetadata((p,a) => ((Slice)p).OnValueChanged(a)));
private void OnValueChanged(DependencyPropertyChangedEventArgs e)
{
// This code never called!
}
}
The problem is that the Value
property on Slice
is never set. If I put the dependency property on the PieChart
and copy the binding expression, then the value is set, so I'm confident that I understand the basics of dependency properties and bindings.
So, what do I have to do to have my dependency property set a value on the child item? As these items are in my own collection, are they somehow not in the logical tree recognised by whatever magic makes bindings work?
A simple 'do this' answer would be helpful, but I'd really like to understand what's going wrong here, so I'll accept the most insightful, explanatory answer posted.
EDIT I didn't make it clear but there is some ambient object on the DataContext
of the PieChart
that contains the properties RedCount
, etc. In the past, when I've had a typo in a binding's path (or some other mistake) I've seen warnings in the VS output window at runtime. In this case, I see nothing.