【问题标题】:Binding ContentTemplate绑定内容模板
【发布时间】:2012-09-21 20:21:45
【问题描述】:

对 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>

当我使用它运行时,什么都没有出现。但是,如果我将资源数据模板的内容直接放在内容控件的位置上,一切都会显示得很好(除了它不是我想要的数据驱动方式)。任何帮助/建议将不胜感激。谢谢!

【问题讨论】:

    标签: wpf data-binding mvvm


    【解决方案1】:

    我真的想说你做错了 =)

    将模板存储在 ViewModel 中通常是个坏主意,因为您会将图形对象存储在 VM 中。这应该在视图端完成

    如果您想要根据项目类型或其他任何类型的变量 DataTemplate,这里有一些替代的“更清洁”的解决方案:

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

    假设您在某处有一个 ResourceDictionary,用于测试目的:

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

    解决方案一:使用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 方法是我在知道这些模板选择器之前使用的方法,我不再使用它了

    干杯!

    【讨论】:

    • 看起来模板选择器给了我我需要的东西。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 2011-12-01
    • 2014-06-30
    • 2020-06-15
    • 2020-10-22
    • 2015-04-09
    相关资源
    最近更新 更多