C# 如何从基类的ObservableCollection显示子类的属性?

C# 如何从基类的ObservableCollection显示子类的属性?,c#,wpf,inheritance,mvvm,observablecollection,C#,Wpf,Inheritance,Mvvm,Observablecollection,我正在构建一个WPF应用程序,它只是一个供团队成员编辑xml的UI。在遇到这个问题之前,我的视图模型设置一直运行正常 假设我有一个模型“动物”,其中“狗”和“鸟”都是从它继承来的 在我的viewmodel中,我有属性 public ObservableCollection<AnimalViewModel> Animals {get; set;} publicobservableCollection动物{get;set;} 在我的视图中,我在listview中显示每种动物,但对于鸟

我正在构建一个WPF应用程序,它只是一个供团队成员编辑xml的UI。在遇到这个问题之前,我的视图模型设置一直运行正常

假设我有一个模型“动物”,其中“狗”和“鸟”都是从它继承来的

在我的viewmodel中,我有属性

public ObservableCollection<AnimalViewModel> Animals {get; set;}
publicobservableCollection动物{get;set;}
在我的视图中,我在listview中显示每种动物,但对于鸟类,我希望有一个“CanFly”(企鹅和诸如此类)复选框。如何设置viewmodel和绑定以实现此目的

下面是我当前设置的一个示例

//MODELS
public class Animal
{
    public string Name;
}

public class Dog:Animal
{
    public string Breed;
}

public class Bird:Animal
{
    public bool CanFly;
}

//VIEWMODELS
//PropertyChanged.Fody nuget package
[AddINotifyPropertyChangedInterface]
public class BaseViewModel: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
}

public class AnimalDataVM:BaseViewModel
{
    public ObservableCollection<AnimalVM> Animals{get;set;}
}

public class AnimalVM
{
    private Animal animal;
    public AnimalVM(Animal _animal)
    {
        animal = _animal;
    }

    public string Name
    {
        get
        {
            return animal.Name;
        }
        set
        {
            animal.Name = value;
        }
    }
}

public class BirdVM
{
    private Bird bird;
    public BirdVM(Bird _bird)
    {
        bird = _bird;
    }

    public string Name
    {
        get
        {
            return bird.Name;
        }
        set
        {
            bird.Name = value;
        }
    }

    public bool CanFly
    {
        get
        {
            return bird.CanFly;
        }
        set
        {
            bird.CanFly = value;
        }
    }
}
//模型
公营动物
{
公共字符串名称;
}
公营狗:动物
{
公弦品种;
}
公营鸟类:动物
{
公共图书馆能飞;
}
//视图模型
//PropertyChanged.Fody nuget包
[AddInnotifyPropertyChangedInterface]
公共类BaseViewModel:INotifyPropertyChanged
{
公共事件PropertyChangedEventHandler PropertyChanged=(发送方,e)=>{};
}
公共类AnimalDataVM:BaseViewModel
{
公共可观察收集动物{get;set;}
}
公共类动物
{
私人动物;
公共动物(动物)
{
动物=_动物;
}
公共字符串名
{
得到
{
返回动物名称;
}
设置
{
动物名称=值;
}
}
}
公营鸟笼
{
私人雀鸟;
公共鸟类
{
鸟=鸟;
}
公共字符串名
{
得到
{
返回鸟。名称;
}
设置
{
bird.Name=value;
}
}
公共场所能飞
{
得到
{
返回鸟。会飞;
}
设置
{
bird.CanFly=值;
}
}
}

第一个选项是使用
DataTemplate
。但这需要在
视图模型中有不同的类。但它非常高效且易于实施:

<ListView Name="MyListview">
    <ListView.Resources>
        <DataTemplate DataType="{x:Type local:AnimalViewModel}">
            <TextBlock Text="Animal"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:DogViewModel}">
            <TextBlock Text="Dog"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:BirdViewModel}">
            <StackPanel Orientation="Horizontal">
                <CheckBox Content="Can fly"/>
                <TextBlock Text="Bird"/>
            </StackPanel>
        </DataTemplate>
    </ListView.Resources>
</ListView>

第一个选项是使用
DataTemplate
。但这需要在
视图模型中有不同的类。但它非常高效且易于实施:

<ListView Name="MyListview">
    <ListView.Resources>
        <DataTemplate DataType="{x:Type local:AnimalViewModel}">
            <TextBlock Text="Animal"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:DogViewModel}">
            <TextBlock Text="Dog"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:BirdViewModel}">
            <StackPanel Orientation="Horizontal">
                <CheckBox Content="Can fly"/>
                <TextBlock Text="Bird"/>
            </StackPanel>
        </DataTemplate>
    </ListView.Resources>
</ListView>

欢迎你的问题似乎太宽泛了,如果是如此令人遗憾的话,那么你的问题就太离题了。还有其他要显示的代码吗。祝你好运,先生,欢迎光临。你的问题似乎太宽泛了,如果是如此令人遗憾的话,那么你的问题就太离题了。还有其他要显示的代码吗。如果我使用的是分部类,那么第二个解决方案可能会很好,对吗?我正试图专门处理继承问题。如果有帮助的话,我更新了OP以包含更多信息。是的。关于您的更新,
DataTemplate
似乎是我的最佳实践。唯一的问题是不同模板之间的通用代码,我们不想重复。感谢您迄今为止的帮助!我想也许我误解了什么。如果我有一个observeCollection,数据模板如何知道使用哪种类型?它总是会使用动物,对吗?或者说我完全搞错了这个问题?实际上,
DataTemplate
非常支持多态性。简单地说,为了解析类型,它使用实例化类型,而不是声明类型。如果它不能解析/识别当前类型,它将在不同的基类之间循环。噢,哇!听起来太棒了!明天我会试一试,如果有效的话,把这个标记为已回答。再次感谢!如果我使用的是分部类,那么第二个解决方案可能会很好,对吗?我正试图专门处理继承问题。如果有帮助的话,我更新了OP以包含更多信息。是的。关于您的更新,
DataTemplate
似乎是我的最佳实践。唯一的问题是不同模板之间的通用代码,我们不想重复。感谢您迄今为止的帮助!我想也许我误解了什么。如果我有一个observeCollection,数据模板如何知道使用哪种类型?它总是会使用动物,对吗?或者说我完全搞错了这个问题?实际上,
DataTemplate
非常支持多态性。简单地说,为了解析类型,它使用实例化类型,而不是声明类型。如果它不能解析/识别当前类型,它将在不同的基类之间循环。噢,哇!听起来太棒了!明天我会试一试,如果有效的话,把这个标记为已回答。再次感谢!