リソースを使ってのUIの共通化(データテンプレートをバインディングする)

SilverLight,WPFの話。WPFでは試していないけど、たぶん出来るだろ。
本当にこういうテクニックでいいのかは謎だけど、とりあえず動いたので。

同じようなもの(たとえばグラフなど)を複数配置するしたいという要望があるのだけど、XAMLのコピーでも済ますのは、数が少ないならまぁいいけれど、多くなってくるとメンテナンスが大変だ。そのため、共通化させたい。

真っ当な方法としては、UserContorolを作るというのがあるのだけど、何となく、リソース使えば何とかなるんじゃね?とか思ったら、面倒だけど、何とかなった。その方法を書く。

そもそも、データテンプレートをバインディングするためのクラスが存在しなかった。絶対あるだろ・・とか思ったけど、ないっぽい。
そういうわけで作った。ユーザコントロールを作って、依存プロパティでDataTemplateを追加、そして、コントロールロード時にデータテンプレートを追加するようにする。

    public partial class DataTemplateControl : UserControl
    {
        public DataTmpControl()
        {
            InitializeComponent();
        }

        public DataTemplate DataTemplate
        {               
            get { return (DataTemplate)GetValue(DataTemplateProperty); }
            set { SetValue(DataTemplateProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DataTemplate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataTemplateProperty =
            DependencyProperty.Register("DataTemplate", typeof(DataTemplate), typeof(DataTemplateControl), new PropertyMetadata(null));

        bool loadedFlag = false;
        private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
        {
            if (loadedFlag == false)
            {
                if (DataTemplate != null)
                {
                    var d = DataTemplate.LoadContent() as FrameworkElement;
                    LayoutRoot.Children.Add(d);
                }
                loadedFlag = true;
            }   
        }
    }

これはXAML側でこんな感じに呼び出して使う。リソースはDataTemplateで作っていること。

試していないけど、動的な要素を表示するのに、データテンプレートのプロパティを持たせてやれば、たぶん動的な要素の表示とか出来そう。