依存関係プロパティを子要素に連結する

カスタムコントロールで子要素に値を継承させるにはどうするのが簡単だろうか?

値を継承するカスタムの依存関係プロパティを作る方法 - Yamakiの日記で,StackPanelを継承するコントロールに含まれるButtonに値を継承させる例がある.でも,この方法だといずれのコントロールもクラスを継承して依存関係プロパティをコードで追加してやらないといけない.

結局のところ,カスタムなコントロールに依存プロパティを追加して,子要素からBindingでたどる方法をとりました.依存プロパティ"Text"にTextBlock.Text を使っているのは,メタデータで inheriteを使うわけでもないので,意味ないです.

で,コード.カスタムなコントロールで依存関係プロパティを宣言しておく.継承クラスでない限り,AddOwnerで追加した依存関係プロパティには,もともとのプロパティのメタデータは継承されないとMSDNに明記されていたので,せめてDefaultValueはと指定しておいた.

    public partial class TextBlockWrap : UserControl
    {
        public TextBlockWrap()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty TextProperty = TextBlock.TextProperty.AddOwner(typeof(TextBlockWrap), new PropertyMetadata(string.Empty));
        public String Text
        {
            get { return (String)this.GetValue(TextProperty); }
            set { this.SetValue(TextProperty, value); }
        }
    }

子要素に値を継承するにはXAMLでBindingを記述するのが書きやすい&見やすい.子要素からAncestorTypeを指定して親要素を探して,親要素の依存関係プロパティにBindingしています.親要素に x:Name 属性で名前をつけて,子要素のBindingでElementNameに親要素の名前を指定するほうがよい書き方です.

<UserControl x:Class="WpfApplication1.TextBlockWrap"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:local="clr-namespace:WpfApplication1"             
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:TextBlockWrap}}, Path = Text}" />        
    </StackPanel>
</UserControl>

なんか,いまいち.