WPF:プロパティ値の継承(包含継承)が可能な添付プロパティ
<Window x:Class="WpfApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <GroupBox Header="test" Foreground="Red"> <StackPanel Orientation="Vertical"> <TextBlock Text="test" /> <TextBox Text="test"/> <Button Content="test" /> </StackPanel> </GroupBox> </Window>
上記のようなxamlを実行した場合、GroupBoxのForegroundプロパティの値を子のアイテムが引き継ぐことがあります。 この動きを、プロパティの値の継承と呼びます。(クラスの派生による継承とは異なることから、「包含継承」と呼ぶことがあるようです。)
上記の例では、TextBlockはGroupBoxのForegroundを引き継ぎますが、TextBoxやButtonのForegroundは引き継がれないようです。
そこで、プロパティ値の継承が可能な添付プロパティを作成し、そのプロパティが設定されたコントロールのForegruondを強制的に書き換えるようにしてみます。
public class Att { public static Brush GetForeground(DependencyObject obj) { return (Brush)obj.GetValue(ForegroundProperty); } public static void SetForeground(DependencyObject obj, Brush value) { obj.SetValue(ForegroundProperty, value); } public static readonly DependencyProperty ForegroundProperty = DependencyProperty.RegisterAttached("Foreground", typeof(Brush), typeof(Att), new FrameworkPropertyMetadata(null, OnForegroundChanged) { Inherits = true }); private static void OnForegroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var ctl = d as Control; if (ctl == null) return; ctl.Foreground = e.NewValue as Brush; } }
<Window …> <GroupBox Header="test" local:Att.Foreground="Red"> <StackPanel Orientation="Vertical"> <TextBlock Text="test" /> <TextBox Text="test"/> <Button Content="test" /> </StackPanel> </GroupBox> </Window>
上記の添付プロパティを付けると、Foregroundが強制的に変更されます。