Robert Jordan Robert Jordan - 3 years ago 168
C# Question

How to implement dependency property value inheritance in different control types

A have a collection of custom controls I'm creating that each have base classes of their respective controls. Because they each have different base controls, they can't share the exact same dependency property. Is it possible to link dependency properties together so that they can cascade from each other? (Not sure if I'm using the term cascade correctly grammar-wise)

public class RCTWindow : ContentControl {
public static readonly DependencyProperty RemapColorProperty =
DependencyProperty.RegisterAttached(
"RemapColor",
typeof(RemapColors),
typeof(RCTWindow),
new FrameworkPropertyMetadata(
RemapColors.SeaGreen,
FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
new PropertyChangedCallback(OnVisualChanged)));
//...
}
public class RCTButton : Button {
public static readonly DependencyProperty RemapColorProperty =
DependencyProperty.RegisterAttached(
"RemapColor",
typeof(RemapColors),
typeof(RCTButton),
new FrameworkPropertyMetadata(
RemapColors.SeaGreen,
FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
new PropertyChangedCallback(OnVisualChanged)));
//...
}


Here's the xaml. When setting the parent control's remap color, the button does not cascade it by default.

<local:RCTWindow RemapColor="IndianRed">
<local:RCTButton/>
</local:RCTWindow>

Answer Source

You should not declare multiple indepedent attached properties, because there won't be any property value inheritance between them.

Instead, declare a single attached property, and use DependencyProperty.AddOwner in the control classes.

public static class RCT
{
    public static readonly DependencyProperty RemapColorProperty =
        DependencyProperty.RegisterAttached(
            "RemapColor", typeof(RemapColors), typeof(RCT),
            new FrameworkPropertyMetadata(RemapColors.SeaGreen,
                FrameworkPropertyMetadataOptions.Inherits |
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

    public static RemapColors GetRemapColor(DependencyObject obj)
    {
        return (RemapColors)obj.GetValue(RemapColorProperty);
    }

    public static void SetRemapColor(DependencyObject obj, RemapColors value)
    {
        obj.SetValue(RemapColorProperty, value);
    }
}

public class RCTButton : Button
{
    public static readonly DependencyProperty RemapColorProperty =
        RCT.RemapColorProperty.AddOwner(
            typeof(RCTButton), new FrameworkPropertyMetadata(OnVisualChanged));

    public RemapColors RemapColor
    {
        get { return (RemapColors)GetValue(RemapColorProperty); }
        set { SetValue(RemapColorProperty, value); }
    }

    private static void OnVisualChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        Debug.WriteLine("RCTButton.OnVisualChanged: {0}", ((RCTButton)obj).RemapColor);
    }
}

public class RCTWindow : ContentControl
{
    public static readonly DependencyProperty RemapColorProperty =
        RCT.RemapColorProperty.AddOwner(
            typeof(RCTWindow), new FrameworkPropertyMetadata(OnVisualChanged));

    public RemapColors RemapColor
    {
        get { return (RemapColors)GetValue(RemapColorProperty); }
        set { SetValue(RemapColorProperty, value); }
    }

    private static void OnVisualChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        Debug.WriteLine("RCTWindow.OnVisualChanged: {0}", ((RCTWindow)obj).RemapColor);
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download