绑定ContentTemplate

use*_*291 1 data-binding wpf mvvm

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

这是我尝试过的事情之一的示例:

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>
Run Code Online (Sandbox Code Playgroud)

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

NodeTypeView = (DataTemplate)Application.Current.FindResource("TypeTest");
Run Code Online (Sandbox Code Playgroud)

资源XAML:

<DataTemplate x:Key="TypeTest">
<TextBlock Margin="2,6">
  <TextBlock Text="{Binding Path=PropertyName}" />
</TextBlock>
Run Code Online (Sandbox Code Playgroud)

当我这样做时,什么都没有显示。但是,如果我直接将资源数据模板的内容替换为内容控件,则一切都会很好地显示出来(除了它不是我所希望的数据驱动)。任何帮助/建议将不胜感激。谢谢!

Dam*_*cus 5

我真的会说你主要是在做错=)

将模板存储在ViewModel中通常不是一个好主意,因为您将在VM中存储图形对象。这应该在“查看”端完成

如果您要根据商品的类型或其他类型使用变量DataTemplate,请使用以下几种“更清洁”的解决方案:

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

假设您有一个ResourceDictionary带有以下内容的地方,用于测试:

<DataTemplate x:Key="Template1" />
<DataTemplate x:Key="Template2" />
<DataTemplate x:Key="Template3" />
Run Code Online (Sandbox Code Playgroud)

解决方案1:使用 ItemTemplateSelector

(干净的解决方案恕我直言)对于这件事,我会重定向到这个优秀的教程,教我如何使用它 。如果我能理解,没有办法,你不能= d

解决方案2:在您的计算机中使用转换器 Binding

让我们Binding通过使用转换器将其绑定到当前对象本身上来稍微更改一下

<DataTemplate>
      <ContentControl ContentTemplate="{Binding Converter={StaticResource MyConverter}}" />
    </DataTemplate>
Run Code Online (Sandbox Code Playgroud)

这是您的转换器的外观(注意: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!
    }
}
Run Code Online (Sandbox Code Playgroud)

这将为您解决问题

我猜这两种解决方案都可以使用,而且更干净,但是请注意,这是的确切目标ItemTemplateSelector。这种Converter方法是我在了解那些模板选择器之前使用的方法,我不再使用它了

干杯!