我想在一個ListBox中公開兩個派生類型:OutFlight和InFlight都從Flight是一個抽象類型派生。MVVM - 具有多態性的集合
MVVM說我必須爲ListBox的綁定模型設置一個ViewModel。這對於一種類型的揭示並不重要,但我的列表框包含兩種派生類型,而且我正在尋找最佳的MVVM方法。這是否意味着我必須爲每個派生類型設置繼承的ViewModels?我讀過某處ViewModel繼承是不推薦的......我確定這是一個很常見的情況
我想在一個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