如何显示 base class 的 ObserveableCollection 中子 classes 的属性?
How to display properties of child classes from ObserveableCollection of base class?
我正在构建一个 WPF 应用程序,它只是一个 UI 供团队成员编辑 xml。在我 运行 遇到这个问题之前,我的视图模型设置运行良好。
假设我有一个模型 "Animal","Dog" 和 "Bird" 继承自它。
在我的视图模型中,我有 属性
public ObservableCollection<AnimalViewModel> Animals {get; set;}
在我看来,我在列表视图中显示每只动物,但对于鸟类,我希望有一个 "CanFly"(企鹅等)的复选框。我如何设置我的视图模型和绑定来执行此操作?
下面是我当前设置的示例。
//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;
}
}
}
第一个选项是使用 DataTemplate
。但这要求您在 ViewModel
中有不同的 类。然而它非常高效且易于实施:
<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>
如果您的 ViewModel
中不能有不同的类型,那么您应该使用 Style
DataTrigger
和您的 类 属性:
<ListView Name="MyListview">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Content="Can fly">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsBird}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
<TextBlock Text="Anything"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我正在构建一个 WPF 应用程序,它只是一个 UI 供团队成员编辑 xml。在我 运行 遇到这个问题之前,我的视图模型设置运行良好。
假设我有一个模型 "Animal","Dog" 和 "Bird" 继承自它。
在我的视图模型中,我有 属性
public ObservableCollection<AnimalViewModel> Animals {get; set;}
在我看来,我在列表视图中显示每只动物,但对于鸟类,我希望有一个 "CanFly"(企鹅等)的复选框。我如何设置我的视图模型和绑定来执行此操作?
下面是我当前设置的示例。
//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;
}
}
}
第一个选项是使用 DataTemplate
。但这要求您在 ViewModel
中有不同的 类。然而它非常高效且易于实施:
<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>
如果您的 ViewModel
中不能有不同的类型,那么您应该使用 Style
DataTrigger
和您的 类 属性:
<ListView Name="MyListview">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Content="Can fly">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsBird}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
<TextBlock Text="Anything"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>