【问题标题】:How can I programmatically add controls to a DataTemplate defined in XAML?如何以编程方式将控件添加到 XAML 中定义的 DataTemplate?
【发布时间】:2012-05-31 15:02:28
【问题描述】:

我设置了一个简单的 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。

例如

                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 添加控件?

【问题讨论】:

  • 你为什么要这样做?我只能强烈劝阻你这样做。这听起来很有用,但实际上我不认为你想要那样。否则,您始终可以使用 Usercontrols 或 ContentControls 来定义模板的“部分”,这些部分将再次使用不同的模板或模板选择器进行解析。否则,只需为所有不同的表示创建一个数据模板,和/或使用触发器来隐藏它的某些部分。
  • 当我显示 paramItem 时,如果满足“条件”,我想在弹出窗口中显示 paramItem 以强制用户为其输入值。我能看到的唯一可能是在选择数据模板时。如果需要,在参数周围包裹一个弹出窗口似乎是合乎逻辑的。在 XAML 中为每个参数创建完全相同的 dataTemplate 只是为了将其包装在弹出窗口中似乎并不正确。
  • @dowhilefor 考虑到这一点,您还有其他建议吗?
  • 就像我说的,我为这些额外的控件创建了一个数据模板,并使用 ContentControl 添加它们,没有特殊绑定,只是另一个 ContentTemplate。效果很好。
  • @dowhilefor 我需要做的就是在满足条件时在弹出窗口中显示控件,我觉得必须有一个更好的解决方案,然后复制每个控件模板并在其周围放置一个

标签: wpf datatemplate add


【解决方案1】:

试试这个

...
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;
}

【讨论】:

  • 值得指向FrameworkElementFactory的备注部分。
  • OP 询问如何将 xaml 中定义的数据模板添加到我回答的 FrameworkElementFactory 中。我个人使用 XAMLReader 从字符串加载 XAML。
  • 我没有判断您的答案,它完全有效,但应该清楚的是,未来版本可能不支持这,另一方面,这不太可能。
猜你喜欢
  • 2013-03-09
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-29
  • 2016-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多