C# MVVM-具有多态性的集合
我试图在列表框中公开两个派生类型:OutFlight和InFlight都派生自Flight,这是一个抽象类型C# MVVM-具有多态性的集合,c#,wpf,mvvm,.net-4.0,C#,Wpf,Mvvm,.net 4.0,我试图在列表框中公开两个派生类型:OutFlight和InFlight都派生自Flight,这是一个抽象类型 MVVM说我必须为ListBox的绑定模型设置一个ViewModel。公开一种类型并不是什么大问题,但我的listbox包含两种派生类型,我正在寻找最好的MVVM方法。这是否意味着我必须为每个派生类型设置继承的ViewModels?我在某个地方读到过,不建议使用ViewModel继承。。。我相信这是一种非常常见的情况,有几种方法。一种方法是为Flight类编写ViewModel,并用这些
MVVM说我必须为ListBox的绑定模型设置一个ViewModel。公开一种类型并不是什么大问题,但我的listbox包含两种派生类型,我正在寻找最好的MVVM方法。这是否意味着我必须为每个派生类型设置继承的ViewModels?我在某个地方读到过,不建议使用ViewModel继承。。。我相信这是一种非常常见的情况,有几种方法。一种方法是为Flight类编写ViewModel,并用这些“FlightViewModel”对象填充集合。该ViewModel可以包含从“Flight”继承的所有对象。如果您的“InFlight”和“OutFlight”类没有那么复杂,我会将它们封装在一个ViewModel中(这里是“FlightViewModel”) 另一种方法是使用一些基本ViewModel类型的集合作为ListBox项源。该集合包含一些类型为“InFlightViewModel”的ViewModels,以及一些类型为“OutFlightViewModel”的ViewModels。对于列表框项目,可以编写ItemTemplateSelector,为项目类型选择正确的ItemTemplate
public class MainWindowViewModel
{
public ObservableCollection<ViewModelBase> Flights { get; set; }
public MainWindowViewModel()
{
Flights = new ObservableCollection<ViewModelBase>();
Flights.Add(new InFlightViewModel());
Flights.Add(new OutFlightViewModel());
}
}
public class FlightTemplateSelector : DataTemplateSelector
{
public DataTemplate InFlightTemplate { get; set; }
public DataTemplate OutFlightTemplate { get; set; }
public override DataTemplate SelectTemplate(object item,
DependencyObject container)
{
if(item.GetType() == typeof(InFlight))
return InFlightTemplate;
if(item.GetType() == typeof(OutFlight))
return OutFlightTemplate
//Throw exception or choose some random layout
throw new Exception();
}
}
<local:FlightTemplateSelector
x:Key="FlightTemplateSelector">
<local:FlightTemplateSelector.InFlightTemplate>
<!-- Define your layout here -->
</local:FlightTemplateSelector.InFlightTemplate>
<!-- Define your layout here -->
<local:FlightTemplateSelector.OutFlightTemplate>
</local:FlightTemplateSelector.OutFlightTemplate>
</local:FlightTemplateSelector>
公共类MainWindowViewModel
{
公共可观测收集航班{get;set;}
公共主窗口视图模型()
{
航班=新的ObservableCollection();
Flights.Add(新的InFlightViewModel());
Flights.Add(新的视图模型());
}
}
公共类FlightTemplateSelector:DataTemplateSelector
{
公共数据模板InFlightTemplate{get;set;}
公共数据模板{get;set;}
公共覆盖数据模板SelectTemplate(对象项,
DependencyObject(对象容器)
{
if(item.GetType()==typeof(飞行中))
返回模板;
if(item.GetType()==typeof(outlight))
返回模板
//抛出异常或选择一些随机布局
抛出新异常();
}
}
您可以创建一个通用视图模型FlightViewModel,该模型封装出射和入射实体。因此,FlightViewModel具有所有公共属性,并基于出射和入射实体构建(例如,通过在构造函数中传递它们)。它可以有一个附加属性,指示它是出射还是入射(作为枚举或其他内容)
这样做使FlightViewModel基本上成为具体类型Outlight和InFlight的抽象。FlightViewModel还将仅包含视图中实际需要的属性,并采用正确的格式,以便视图可以轻松使用
然后,视图的视图模型将具有FlightViewModel对象的集合
public class FlightViewModel
{
private Flight _flight;
public FlightViewModel(OutFlight outFlight)
{
FlightNumber = outFlight.FlightNumber;
FlightType = FlightType.OutFlight;
_flight = outFlight;
}
public FlightViewModel(InFlight inFlight)
{
FlightNumber = inFlight.FlightNumber;
FlightType = FlightType.InFlight;
_flight = inFlight;
}
public int FlightNumber
{
get { return _flight.FlightNumber; }
set { _flight.FlightNumber = value; }
}
public FlightType FlightType { get; set; }
... other properties
}
当然,这只是一个示例,但您明白了。如果您的ViewModel将其作为ListBox源列表ListBoxSource;有什么问题吗?您想为列表框的项目创建一个ViewModel,对吗?一点示例代码会有所帮助。
public class FlightViewModel
{
private Flight _flight;
public FlightViewModel(OutFlight outFlight)
{
FlightNumber = outFlight.FlightNumber;
FlightType = FlightType.OutFlight;
_flight = outFlight;
}
public FlightViewModel(InFlight inFlight)
{
FlightNumber = inFlight.FlightNumber;
FlightType = FlightType.InFlight;
_flight = inFlight;
}
public int FlightNumber
{
get { return _flight.FlightNumber; }
set { _flight.FlightNumber = value; }
}
public FlightType FlightType { get; set; }
... other properties
}