显示每个类对象

时间:2015-12-16 04:24:09

标签: c# wpf xaml mvvm

假设我在列表中有一些名为属性的类对象。在我的情况下,我想绑定到此列表并显示每个Class对象的不同用户控件。有没有办法做到这一点?

下面的代码似乎显示所有类,无论它们的类型如何,如果我没有它的数据模板,我会假设它不显示项类型。

public class Attribute
{
    public string Key { get; set; }
}

public class FloatAttr : Attribute
{
    public float Value { get; set; }
    public string Label { get; set; }
    private float minValue { get; set; }
    private float maxValue { get; set; }
}

public class IntAttr : Attribute
{
    public int Value { get; set; }
    public string Label { get; set; }
    private float minValue { get; set; }
    private float maxValue { get; set; }
}

public class StringAttr : Attribute
{
    public string Value { get; set; }
    public string Label { get; set; }
}

public class BoolAttr : Attribute
{
    public bool Value { get; set; }
    public string Label { get; set; }
}

MainWindow.xaml

<ListView x:Name="AssetList" ItemsSource="{Binding Attributes}" SelectionMode="Extended">
    <ListBox.Resources>

        <DataTemplate DataType="{x:Type model:IntAttr}">
            <WrapPanel>
                <TextBlock Text="{Binding Key}" Foreground="Blue"></TextBlock>
                <TextBlock Text=" "></TextBlock>
                <TextBlock Text="{Binding Value}"></TextBlock>
            </WrapPanel>
        </DataTemplate>

        <DataTemplate DataType="{x:Type model:BoolAttr}">
            <WrapPanel>
                <TextBlock Text="{Binding Key}" Foreground="Red"></TextBlock>
                <TextBlock Text=" "></TextBlock>
                <TextBlock Text="{Binding Value}"></TextBlock>
            </WrapPanel>
        </DataTemplate>

    </ListBox.Resources>
</ListView>

2 个答案:

答案 0 :(得分:3)

MVVM方式是创建ResourceDictionary

<ResourceDictionary .....>
    <DataTemplate DataType="{x:Type Attribute}">
        <views:AttributeView />
    </DataTemplate>

    <DataTemplate DataType="{x:Type FloatAttr }">
        <views:FloatAttrView />
    </DataTemplate>

    <DataTemplate DataType="{x:Type IntAttr }">
        <views:IntAttrView />
    </DataTemplate>

当然,每个班级都有一个视图(用户控件)。然后你需要注册你创建的字典:

ResourceDictionary MyResourceDictionary = new ResourceDictionary();
MyResourceDictionary.Source = new Uri(ResourceDictionarypath, UriKind.Relative);
if ((Application.Current != null) && (Application.Current.Resources != null))
{
    Application.Current.Resources.MergedDictionaries.Add(MyResourceDictionary);
}

或者,或者,如用户Greg D建议的那样,您可以使用分配给ItemTemplateSelector的simpleDataTemplateSelector来分配正确的模板。如果您使用的映射比简单的1:1稍微复杂一点,或者如果您有多个与同一底层VM关联的数据模板,则此功能非常有用。

答案 1 :(得分:1)

这些是多个问题,但我会尝试回答:

要使您的类具有通用性,您必须将其更改为:

public class Attribute<TValue>
{
    public string Key { get; set; }
    public TValue Value { get; set; }
}

然后,您必须更改子类。重复KeyValue属性是没有意义的,因为它们将被继承。因此,作为示例,FloatAttr类将如下所示:

public class FloatAttr : Attribute<float>
{
    public string Label { get; set; }
    private float minValue { get; set; }
    private float maxValue { get; set; }
}

现在,当您执行此操作时,无法创建List<Attribute>(因为没有type参数,Attribute类不能存在)。因此,除非您有另一个基类,否则必须使用List<object>

在WPF中,您需要做的就是为类定义数据模板。您可以在资源字典或控件级别执行此操作。例如,在窗口上:

<Window.Resources>
    <DataTemplate DataType="{x:Type local:IntAttr}">
        <TextBlock>Int</TextBlock>
        <!-- Int-specific controls -->
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:FloatAttr}">
        <TextBlock>Float</TextBlock>
        <!-- Float-specific controls -->
    </DataTemplate>
</Window.Resources>

请注意,您必须定义XML命名空间(此处称为local)以指向定义类的命名空间。 然后,您只需将对象列表绑定到任何ItemsControl

顺便说一句,#字符不是C#中的注释。