MVVM - 具有多态性的集合
我想在一个ListBox中公开两个派生类型:OutFlight和InFlight都从Flight是一个抽象类型派生。MVVM - 具有多态性的集合
MVVM说我必须为ListBox的绑定模型设置一个ViewModel。这对于一种类型的揭示并不重要,但我的列表框包含两种派生类型,而且我正在寻找最佳的MVVM方法。这是否意味着我必须为每个派生类型设置继承的ViewModels?我读过某处ViewModel继承是不推荐的......我确定这是一个很常见的情况
您可以创建封装OutFlight和InFlight实体的通用视图模型FlightViewModel。因此,FlightViewModel具有所有公共属性,并且基于OutFlight和InFlight实体构造(例如通过在构造函数中传递它们)。它可以有一个额外的属性,表明它是出局还是机上(作为枚举或某物)。
这样做使得FlightViewModel基本上是您的具体类型OutFlight和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
}
这仅仅是一个例子,但你明白了。
有几种方法。一种方法是为您的Flight类编写一个ViewModel,并用这些“FlightViewModel”对象填充一个集合。该ViewModel可以包含从“Flight”继承的所有对象。如果你的“InFlight”和“OutFlight”类不那么复杂,我会把它们包装在一个ViewModel中(这里是“FlightViewModel”)。
public class FlightViewModel : INotifyPropertyChanged
{
public Flight Flight { get; set; }
public int PropertyYouNeedForInFlight { get; set; }
public string PropertyYouNeedForOutFlight { get; set; }
}
用其它方法是使用一些基本的视图模型类型列表框的ItemsSource的集合。该集合包含一些类型为“InFlightViewModel”的ViewModel和一些其他类型为“OutFlightViewModel”的ViewModel。对于您的ListBox项目,您可以编写一个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>
你想要一个ViewModel列表框的项目正确吗? – Andre 2013-04-10 10:34:41
一些示例代码会有所帮助。 – 2013-04-10 10:37:51
如果您的ViewModel包含此列表框源列表 ListBoxSource;它有什么问题? –
2013-04-10 10:32:52