<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="504"> <StackPanel> <StackPanel Orientation="Horizontal"> <Button Name="button1" Click="button1_Click">Lock Outer</Button> <Button Name="button2" Click="button2_Click">Unlock Outer</Button> <Button Name="button3" Click="button3_Click">Lock Inner</Button> <Button Name="button4" Click="button4_Click">Unlock Inner</Button> <Button Height="23" Name="button6" Width="75" Click="button6_Click">Lock R3</Button> <Button Height="23" Name="button5" Width="75" Click="button5_Click">Unlock R3</Button> </StackPanel> <StackPanel> <Label Content="{Binding ElementName=scTest,Path=ContentIsLocked}" ></Label> <Label Content="{Binding ElementName=InnerShapeCanvas3,Path=ContentIsLocked}" ></Label> <loc:ShapeCanvas3 x:Name="scTest" Height="172"> <StackPanel Canvas.Left="46" Canvas.Top="38" Height="100" x:Name="spnlTest" Width="200" > <Rectangle Height="100" x:Name="rectangle1" Stroke="Black" Width="250" Fill="Azure" loc:ShapeCanvas3.ContentIsLocked="false"/> <loc:ShapeCanvas3 x:Name="InnerShapeCanvas3"> <Rectangle Height="100" x:Name="rectangle3" Stroke="Black" Width="250" Fill="Azure" loc:ShapeCanvas3.ContentIsLocked="true" /> <Rectangle Height="100" x:Name="rectangle4" Stroke="Black" Width="250" Fill="Azure" loc:ShapeCanvas3.ContentIsLocked="false"/> </loc:ShapeCanvas3> <Rectangle Height="100" x:Name="rectangle2" Stroke="Black" Width="200" Fill="Azure" /> </StackPanel> </loc:ShapeCanvas3> </StackPanel> </StackPanel> </Window>and
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("**************************"); Debug.Indent(); Debug.WriteLine("Setting outer to True"); scTest.ContentIsLocked = true; Debug.Unindent(); Debug.WriteLine("*********End*********"); } private void button2_Click(object sender, RoutedEventArgs e) { Debug.WriteLine("**************************"); Debug.Indent(); Debug.WriteLine("Setting outer to False"); scTest.ContentIsLocked = false; Debug.Unindent(); Debug.WriteLine("*********End*********"); } private void button3_Click(object sender, RoutedEventArgs e) { Debug.WriteLine("**************************"); Debug.Indent(); Debug.WriteLine("Setting inner to True"); InnerShapeCanvas3.ContentIsLocked = true; Debug.Unindent(); Debug.WriteLine("*********End*********"); } private void button4_Click(object sender, RoutedEventArgs e) { Debug.WriteLine("**************************"); Debug.Indent(); Debug.WriteLine("Setting inner to False"); InnerShapeCanvas3.ContentIsLocked = false; Debug.Unindent(); Debug.WriteLine("*********End*********"); } private void button5_Click(object sender, RoutedEventArgs e) { ShapeCanvas3.SetContentIsLocked(rectangle3, false); } private void button6_Click(object sender, RoutedEventArgs e) { ShapeCanvas3.SetContentIsLocked(rectangle3, true); } } 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 static void SetContentIsLocked(FrameworkElement element, bool value) { Debug.WriteLine("SetContentIsLocked to " + value.ToString() + " on " + element.Name); element.SetValue(ContentIsLockedProperty, value); //Property is not changed anyway if false so this option doesn't make any difference: //if (value) // element.SetValue(ContentIsLockedProperty, value); //else // element.SetValue(ContentIsLockedProperty, DependencyProperty.UnsetValue); } public static bool GetContentIsLocked(FrameworkElement element) { Debug.WriteLine("GetContentIsLocked for " + element.Name); return (bool)element.GetValue(ContentIsLockedProperty); } public bool ContentIsLocked { set { if (value) { Debug.WriteLine("ContentIsLocked.SetValue to true"); SetValue(ContentIsLockedProperty, value); } else { Debug.WriteLine("ContentIsLocked.SetValue to unset"); this.ClearValue(ContentIsLockedProperty); } } get { return (bool)GetValue(ContentIsLockedProperty); } } private static void OnContentIsLockedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { Debug.WriteLine("ContentIsLockedChanged on " + ((FrameworkElement)obj).Name + " from " + e.OldValue.ToString() + " to " + e.NewValue.ToString()); } private static object CoerceIsLocked(DependencyObject d, object value) { Debug.WriteLine("--------"); Debug.Indent(); Debug.WriteLine("Coerce called for " + ((FrameworkElement)d).Name); Debug.WriteLine("Current Value is " + d.ReadLocalValue(ContentIsLockedProperty).ToString()); Debug.WriteLine("Requested value is " + value.ToString()); Debug.Unindent(); Debug.WriteLine("--------"); return value; //This actually messes things up! //return (bool)value ? value : DependencyProperty.UnsetValue; } } }Best,