<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,
//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);>