[英]WPF implicit datatemplate with observablecollection
我是WPF新手並使用MVVM。 我有一個視圖,我想根據用戶在菜單上選擇的內容顯示不同的內容。 其中一個是另一個用戶控件Temp,它有一個視圖模型(TempVM)所以我這樣做:
<ContentControl Content="{Binding Path=TempVM}"/>
並且TempVM(類型為TempViewModel)在用戶單擊按鈕之前為空。 它的數據模板是這樣的
<DataTemplate DataType="{x:Type vm:TempViewModel}">
<view:Temp />
</DataTemplate>
這沒關系,但我要做的另一件事是當用戶點擊不同的菜單項時顯示一個列表框。 所以我想做
<ContentControl Content="{Binding Path=Missions}"/>
(任務是一個可觀察的MissionData集合)並試圖模仿它:
<DataTemplate DataType="{x:Type ObservableCollection(MissionData)}">
<StackPanel>
<ListBox ItemsSource="{Binding}" SelectedItem="{Binding Path=MissionData, Mode=TwoWay}" DisplayMemberPath="MissionName" SelectedValuePath="MissionId" />
<Button Content="Go"/>
</StackPanel>
</DataTemplate>
但是編譯器不喜歡類型引用。 如果我嘗試通過給模板一個鍵並在ContentControl中指定該鍵它可以工作但顯然我看到ListBox和按鈕沒有任務時。 顯然,我可以創建一個用戶控件和視圖模型,並遵循與TempVM相同的模式,但它似乎超越了頂部。 我是否正確地對待這個問題,我需要做什么?
從我看到的是你嘗試使用Collection作為數據對象,這在我看來是不好的做法。 擁有DataTemplate的集合也存在問題,就像您已經見過的那樣。 我建議你使用ViewModel作為你的任務集合。
class MissionsSelectionViewModel
{
public ObservableCollection<Mission> Misssions;
public MissionData SelectedMission;
public ICommand MissionSelected;
}
並將您的datatemplate修改為
<DataTemplate DataType="{x:Type MissionsSelectionViewModel}">
<StackPanel>
<ListBox ItemsSource="{Binding Missions}" SelectedItem="{Binding Path=MissionData, Mode=TwoWay}" DisplayMemberPath="MissionName" SelectedValuePath="MissionId" />
<Button Content="Go" Command="{Binding MissionSelected}/>
</StackPanel>
</DataTemplate>
如果我要遵循隱式模板的模式,我將從ObservableCollection<MissionData>
派生一個自定義的非泛型集合MissionDataCollection
,並使用它來保存MissionData
項目。 然后我只想在DataType
引用該集合。 此解決方案提供了其他優點,例如有用的集合上的事件聚合。
但是,在我看來,最好的解決方案如下。
IsMissionsListVisible
屬性添加到VM。 ContentControl
的Visibility
屬性綁定到IsMissionsListVisible
屬性。 DataTemplate
資源。 IsMissionsListVisible
的邏輯。 據推測,當所選項目中至少有一個任務時,它應該是真的。 但邏輯可能更復雜。 我會這樣做的。 事實上,我通常這樣做,它有幾個好處。 最重要的是我可以在各種情況下明確控制內容可見性的邏輯(例如異步內容刷新)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.