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

本文关键字:类型 加载 控件 绑定 何根 WPF | 更新日期: 2023-09-27 18:17:32

我有一个问题,我已经解决了自己,但我不喜欢的解决方案,因为它的复杂性和依赖性的很多事件,它不是根据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; }
}

我有一个基类对象的可观察集合。

ObservableCollection<CommonBaseClass> DataCollection = new ObservableCollection<CommonBaseClass>(); 

Collection" DataCollection"被绑定到itemscontrol.

    <ItemsControl ItemsSource="{Binding DataCollection}">
    </ItemsControl>

我想将集合绑定到itemscontrol的方式,根据继承基类的类型,将加载不同的控件并以最大的自定义绑定

因此,如果控件中的一个项目是TextClass的类型,该对象将被绑定到一个标签,如果它是TrueClass的类型,它将被绑定到一个ChackBox,如果它是CateClass,它将被绑定到自定义UserControl,其中包含一个DatePicker, textBox和一个执行一些代码的按钮。

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

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

我正在使用转换器、模板和资源字典(也合并了),所以我将欣赏真正的"书本解决方案"

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

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

技术细节在MSDN

上描述

使用数据模板选择器。如果您想要一个简化的完整示例,请参阅我对这个堆栈溢出问题的回答。

我曾经解决过一个类似的问题,方法是在ItemControl的ItemTemplate中指定所有三个潜在控件,并根据实际数据类型使用转换器将其中两个控件的Visibility设置为Hidden,一个设置为Visible。这允许您在XAML中设置所有三个控件,包括绑定,而不需要编码滞后或事件代码。

一个问题可能是,在TextClassTrueClass类型的情况下,DatePicker控件仍然存在于DataTemplate中(尽管不可见),并绑定到当前类型中不存在的Name属性-但是没有尝试,我假设XAML足够宽容,可以忽略这种不适当的绑定。