如何以编程方式将控件添加到XAML中定义的DataTemplate?

时间:2012-05-30 14:29:53

标签: wpf datatemplate add

我设置了一个简单的DataTemplateSelector:

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        if (element != null && item != null && item is ParameterViewModel)
        {
            ParameterViewModel paramItem = item as ParameterViewModel;

            if (paramItem.ControlInfo.Type == "slider")
            {
                return element.FindResource("sliderParam") as DataTemplate;
            }
            else if (paramItem.ControlInfo.Type == "button")
            {
                return element.FindResource("buttonParam") as DataTemplate;
            }
                            ...... etc

这一切都很好,我已将它添加到我的XAML中,并且按预期工作。

现在,我想要做的是:如果满足条件,请在返回之前向DataTemplate添加一些额外的控件。 我的第一个尝试是创建一个StackPanel FrameworkElementFactory,并将DataTemplate的VisualTree与我想要添加的额外控件一起添加到它,然后返回一个DataTemplate,并将VisualTree设置为FrameWorkElementFactory。

E.g。

                FrameworkElementFactory spFactory = new FrameworkElementFactory(typeof(StackPanel));

                if (paramItem.ControlInfo.Type == "slider")
                {
                    spFactory.AppendChild((element.FindResource("sliderParam") as DataTemplate).VisualTree);
                }

  ...

                //add my extra controls 
                if(condition..)
                {
                    spFactory.AppendChild(extraControl);
                }

               return new DataTemplate { VisualTree = spFactory };

但是,因为DataTemplate是在XAML中定义的,所以VisualTree属性将始终返回null。

如何将控件添加到DataTemplate?

1 个答案:

答案 0 :(得分:0)

试试这个

...
if (paramItem.ControlInfo.Type == "slider")
{
   spFactory.AppendChild(FactoryFromResource("sliderParam"));
}
...

private FrameworkElementFactory FactoryFromResource(string resource)
{
    DataTemplate dataTemplate = FindResource(resource) as DataTemplate;
    FrameworkElementFactory factory = new FrameworkElementFactory(typeof(ContentControl));
    factory.SetValue(ContentControl.ContentTemplateProperty, dataTemplate);
    return factory;
}