views:

595

answers:

2

I've got a WPF Control that exposes one of it's children (from it's ControlTemplate) through a read-only property. At the moment it's just a CLR property, but I don't think that makes any difference.

I want to be able to set one of the properties on the child control from the XAML where I'm instantiating the main control. (Actually, I would like to bind to it, but I think setting it would be a good first step.)

Here's some code:

public class ChartControl : Control
{
    public IAxis XAxis { get; private set; }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        this.XAxis = GetTemplateChild("PART_XAxis") as IAxis;
    }
}

public interface IAxis
{
    // This is the property I want to set
    double Maximum { get; set; }
}

public class Axis : FrameworkElement, IAxis
{
    public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum", typeof(double), typeof(Axis), new FrameworkPropertyMetadata(20.0, FrameworkPropertyMetadataOptions.AffectsRender, OnAxisPropertyChanged));

    public double Maximum
    {
        get { return (double)GetValue(MaximumProperty); }
        set { SetValue(MaximumProperty, value); }
    }
}

Here's the two ways I can think of setting the nested property in XAML (neither compile):

<!-- 
    This doesn't work:
    "The property 'XAxis.Maximum' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'."
    "The attachable property 'Maximum' was not found in type 'XAxis'."
-->
<local:ChartControl XAxis.Maximum="{Binding Maximum}"/>

<!-- 
    This doesn't work: 
    "Cannot set properties on property elements."
-->
<local:ChartControl>
    <local:ChartControl.XAxis Maximum="{Binding Maximum}"/>
</local:ChartControl>

Is this even possible?

Without it I guess I'll just need to expose DP's on the main control that get bound through to the children (in the template). Not so bad, I guess, but I was just trying to avoid an explosion of properties on the main control.

Cheers.

+1  A: 

You can't do it like this... you can access nested properties through its path in a binding, but not when you define the value of the property.

You have to do something like that :

<local:ChartControl>
    <local:ChartControl.XAxis>
        <local:Axis Maximum="{Binding Maximum}"/>
    </local:ChartControl.XAxis>
</local:ChartControl>
Thomas Levesque
Yeah, that's what I thought. :-(Extra DPs on my top-level control it is, then!
Swythan
BTW. I can't do it as in your example XAML, as I don't want to replace the existing value of the XAxis property with a new instance of Axis.
Swythan
A: 

I'm in the same position. Swythan: What did you finally do? As you stated, the answer above doesn't work since it creates a new Axis object, rather than setting a property on the Axis object. How do you make a DP on ChartControl that affects XAxis?

I gave up and added the extra properties on my top-level control, with a Binding from the top-level property to the nested one. :-(One thing I did do is copy the Chart control in the WPFToolkit and added an "AxisStyle" property of type Style to my top-level control, and bound that to the Style property of all the Axis controls inside. That allows a Style set on the top-level control to contain visual styles for the nested elements without having to redefine the whole ControlTemplate. That didn't help with properties like "Maximum", etc though.
Swythan