C# 如何根据WPF中的数据绑定类类型加载不同的控件

C# 如何根据WPF中的数据绑定类类型加载不同的控件,c#,xaml,mvvm,data-binding,C#,Xaml,Mvvm,Data Binding,我有一个我自己解决的问题,但我不喜欢这个解决方案,因为它的复杂性和许多事件的依赖性,而且它不符合MVVM的指导原则,所以我想以正确的方式来做,并重新考虑它。 我还要强调,这是问题的一个简化例子 首先,我有一个基本类 public abstract class CommonBaseClass { public int ID { get; set; } } 我还有几个从基类继承的类 public class DateClass : CommonBaseClass { public

我有一个我自己解决的问题,但我不喜欢这个解决方案,因为它的复杂性和许多事件的依赖性,而且它不符合MVVM的指导原则,所以我想以正确的方式来做,并重新考虑它。 我还要强调,这是问题的一个简化例子

首先,我有一个基本类

public abstract class CommonBaseClass
{
    public int ID { get; set; }
}
我还有几个从基类继承的类

public class DateClass : CommonBaseClass
{
    public DateTime Value { get; set; }
    public string Name { get; set; }
}

public class TextClass : CommonBaseClass
{
    public string Value { get; set; }
}

public class TrueClass : CommonBaseClass
{
    public bool Value { get; set; }
}
我有一个usercontrol,我有一个可观察的基类对象集合

ObservableCollection<CommonBaseClass> DataCollection = new ObservableCollection<CommonBaseClass>(); 
ObservableCollection DataCollection=新的ObservableCollection();
集合“DataCollection”绑定到itemscontrol

    <ItemsControl ItemsSource="{Binding DataCollection}">

    </ItemsControl>

我希望以一种方式将集合绑定到itemscontrol,这种方式取决于继承基控件的类的类型,将加载不同的控件并以最大的自定义方式进行数据绑定

因此,如果控件中的项是TextClass的类型,则对象将绑定到标签,如果它是TrueClass的类型,则对象将绑定到ChackBox,如果它是CateClass,则对象将绑定到包含日期选择器、textBox和执行某些代码的按钮的自定义UserControl

我已经有了一个有效的解决方案,但在我看来,它确实很糟糕,因为它在转换器中创建了不同的控件,并且它等待不同的加载事件并手动绑定所有内容。就像我说的,真的很糟糕

我确信在XAML中必须有更好的“MVVM方式”来实现这一点

我使用的是转换器、模板和资源字典(也包括合并的),所以我希望真正的“按书解决方案”


提前感谢;)

我曾经通过在ItemControl的
ItemTemplate
中指定所有三个潜在控件解决了类似的问题,并使用转换器根据实际数据类型将其中两个控件的
可见性设置为
隐藏
,一个设置为
可见
。这允许您在XAML中设置所有三个控件,包括绑定,而无需使用codebehing或事件代码


一个问题可能是在
TextClass
TrueClass
类型的情况下,DatePicker控件仍然存在于DataTemplate中(尽管不可见)并绑定到当前类型上不存在的
名称
属性-但如果不尝试,我会假设XAML具有足够的容忍度,可以忽略此不适当的绑定。

如果存在更复杂的逻辑,通常通过使用DataTemplates最终与DataTemplateSelector结合使用来解决此问题涉及如何根据绑定选择正确的模板。 对于所描述的场景,在参考资料中定义特定的数据模板并指定DataTemplate的DataType属性就足够了。 WPF然后根据绑定对象的类型选择正确的模板


有关技术详细信息,请参见使用数据模板选择器。如果您想要一个精简的完整示例,请参阅我的答案

,这比我的解决方案简单,但老实说,我不喜欢这样浪费资源。在我的具体案例中,我有12个不同的子类,平均来说,在一个集合中,大约有100个项目。这可能有点大。你有没有试过使用nope,一分钟前我发现了下面的例子。就在你粘贴它之前。DataTemplateSelektor似乎就是它的解决方案。