绑定ContentTemplate

时间:2012-09-21 20:21:46

标签: wpf data-binding mvvm

WPF和MVVM的新手,我正在尝试将ContentTemplate(或ItemTemplate,既没有工作)绑定到C#WPF程序中的DataTemplate属性。我这样做是因为我有一个配置文件,为每个“条目”定义不同的“条目显示类型”,试图不必制作无数的视图/视图模型(现在,只有一个通用条目视图模型可以跟踪标签,数据和显示类型,我宁愿保持这种方式,以避免不必要的类结构膨胀)。有没有办法让这项工作?

这是我尝试过的一个例子:

XAML:

<ItemsControl IsTabStop="False" ItemsSource="{Binding Path=FNEntries}"Margin="12,46,12,12">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <ContentControl ContentTemplate="{Binding Path=TypeView}" />
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

CS(在入口视图模型类构造函数中有(DataTemplate)TypeView和(string)PropertyName):

NodeTypeView = (DataTemplate)Application.Current.FindResource("TypeTest");

资源XAML:

<DataTemplate x:Key="TypeTest">
<TextBlock Margin="2,6">
  <TextBlock Text="{Binding Path=PropertyName}" />
</TextBlock>

当我跑步时,没有任何东西出现。但是,如果我直接将资源数据模板的内容放在内容控件的位置,那么事情就会很好(除了它不是以我想要的方式进行数据驱动)。任何帮助/建议将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:5)

我真的说你做错了=)

将模板存储在ViewModel中通常是一个坏主意,因为您将在VM中存储图形对象。这应该在View侧进行

如果你想根据你的物品类型或其他任何东西想要一个变量DataTemplate,这里有一些替代的“清洁”解决方案:

先决条件:您的所有模板都在某处定义为资源。

假设你有一个ResourceDictionary以下的地方用于测试目的:

<DataTemplate x:Key="Template1" />
<DataTemplate x:Key="Template2" />
<DataTemplate x:Key="Template3" />

解决方案1:使用ItemTemplateSelector

(最干净的解决方案) 就此而言,我会将您重定向到this excellent tutorial which taught me how to use it 如果我能理解它,你就不能= D

解决方案2:在Binding

中使用转换器

让我们稍微更改你的Binding,使其与当前对象本身绑定,并使用转换器

<DataTemplate>
      <ContentControl ContentTemplate="{Binding Converter={StaticResource MyConverter}}" />
    </DataTemplate>

这是你的转换器的样子(注意:这里的value对象是绑定对象,在你使用它的类型的情况下,所以这个例子也是关于类型的)

public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value.GetType() == typeof(WhateverYouWant))
        {
        return (DataTemplate)Application.Current.FindResource("OneTemplate");
        } 
        else if (value.getType() == typeof(AnotherTypeHere))
        {
        return (DataTemplate)Application.Current.FindResource("AnotherTemplate");
        }
        // other cases here...
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value; //We don't care about this!
    }
}

这可以帮到你

我想这些解决方案都可行,而且更清晰,但要注意这是ItemTemplateSelector的确切目标。我知道有关模板选择器的Converter方法是我使用过的方法,我不再使用它了

干杯!