<Window x:Class="WpfPropertyInheritance.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:loc="clr-namespace:WpfPropertyInheritance" Title="Window1" Height="300" Width="300"> <StackPanel> <Button Height="23" Name="button1" Width="75" Click="button1_Click">Button</Button> <Button Height="23" Name="button2" Width="75" Click="button2_Click">Button</Button> <loc:ShapeCanvas3 x:Name="scTest" Height="172"> <StackPanel Canvas.Left="46" Canvas.Top="38" Height="100" Name="spnlTest" Width="200" > <Rectangle Height="100" Name="rectangle1" Stroke="Black" Width="200" Fill="Azure" /> </StackPanel> </loc:ShapeCanvas3> </StackPanel> </Window>C#:
using System.Windows; using System.Windows.Controls; using System.Diagnostics; namespace WpfPropertyInheritance { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { Debug.WriteLine("A1 Starting Value: " + scTest.ContentIsLocked.ToString()); scTest.ContentIsLocked = true; Debug.WriteLine("A2 Set Canvas True: " + scTest.ContentIsLocked.ToString()); scTest.ContentIsLocked = true; Debug.WriteLine("A3 Set Canvas True Again: " + scTest.ContentIsLocked.ToString()); scTest.ContentIsLocked = false; Debug.WriteLine("A4 Set Canvas False: " + scTest.ContentIsLocked.ToString()); } private void button2_Click(object sender, RoutedEventArgs e) { Debug.WriteLine("B2 Starting Values: " + scTest.ContentIsLocked.ToString()+ ":" + rectangle1.GetValue(ShapeCanvas3.ContentIsLockedProperty).ToString()); scTest.ContentIsLocked = true; Debug.WriteLine("B2 Set Canvas True: " + scTest.ContentIsLocked.ToString() + ":" + rectangle1.GetValue(ShapeCanvas3.ContentIsLockedProperty).ToString()); rectangle1.SetValue(ShapeCanvas3.ContentIsLockedProperty, false); Debug.WriteLine("B2 Set Rect False: " + scTest.ContentIsLocked.ToString() + ":" + rectangle1.GetValue(ShapeCanvas3.ContentIsLockedProperty).ToString()); } } public class ShapeCanvas3 : Canvas { public static DependencyProperty ContentIsLockedProperty; static ShapeCanvas3() { FrameworkPropertyMetadata p = new FrameworkPropertyMetadata( new PropertyChangedCallback(OnContentIsLockedChanged), new CoerceValueCallback(CoerceIsLocked) ); p.Inherits = true; ContentIsLockedProperty = DependencyProperty.RegisterAttached("ContentIsLocked", typeof(bool), typeof(ShapeCanvas3), p); } public bool ContentIsLocked { set { Debug.WriteLine("SetVal: " + value.ToString()); if (value) SetValue(ContentIsLockedProperty, value); else this.ClearValue(ContentIsLockedProperty); } get { return (bool)GetValue(ContentIsLockedProperty); } } private static void OnContentIsLockedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { } private static object CoerceIsLocked(DependencyObject d, object value) { if (d.ReadLocalValue(ContentIsLockedProperty) == DependencyProperty.UnsetValue) { Debug.WriteLine("Coerce 1: "+d.ToString()+":" + value.ToString()); return value; } bool b = (bool)value; if (b) { Debug.WriteLine("Coerce 2: " + b.ToString()); return b; } else { Debug.WriteLine("Coerce 3: UnsetValue"); return DependencyProperty.UnsetValue; } } } }Here is the debug output on the second button:
B2 Starting Values: False:False SetVal: True Coerce 1: WpfPropertyInheritance.ShapeCanvas3:True Coerce 1: System.Windows.Controls.StackPanel:True Coerce 1: System.Windows.Shapes.Rectangle:True B2 Set Canvas True: True:True Coerce 1: System.Windows.Shapes.Rectangle:False B2 Set Rect False: True:FalseB2 Set Rect False: True:False = Canvas is locked, but child was able to be unlocked.