wpf - 绑定(bind)内容模板

标签 wpf data-binding mvvm

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

这是我尝试过的其中一件事的示例:

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 的入口 View 模型类构造函数内):
NodeTypeView = (DataTemplate)Application.Current.FindResource("TypeTest");

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



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

最佳答案

我真的会说你大多做错了=)

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

如果您想要根据项目类型或其他任何类型的变量 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 ,通过使用转换器使其绑定(bind)到当前对象本身
<DataTemplate>
      <ContentControl ContentTemplate="{Binding Converter={StaticResource MyConverter}}" />
    </DataTemplate>

这是您的转换器的样子(注意:这里的 value 对象是绑定(bind)对象,在您的情况下,您正在使用它的类型,所以这个例子也是关于类型的)
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方法是我在了解这些模板选择器之前使用的方法,我不再使用它了

干杯!

关于wpf - 绑定(bind)内容模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12537658/

相关文章:

WPF 如何创建一个漂亮的字母波浪

c# - 以编程方式将 List 绑定(bind)到 ListBox

java - Android MVVM 谁应该读取和存储包

c# - 如何在 WPF 中制作具有单个捕捉点的 Slider 控件?

c# - 如何禁止窗口自动最大化?

c# - WPF,将键盘焦点提供给以前折叠的控件

c# - Caliburn.Micro 无法匹配来自不同程序集的 View 和 ViewModel

wpf - 如何刷新 WPF DataGrid?

asp.net-mvc - 在 ASP.NET MVC 中将引用数据加载到 View 模型中的可靠方法

wpf - 调整窗口大小和绑定(bind)未按预期运行