WPF隐式datatemplate与observablecollection

时间:2012-04-18 08:37:28

标签: c# wpf

我是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}"/>

(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相同的模式,但它似乎超越了顶部。我是否正确地对待这一点以及我需要做什么?

2 个答案:

答案 0 :(得分:2)

从我看到的是你尝试使用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>

答案 1 :(得分:1)

如果我要遵循隐式模板的模式,我会从MissionDataCollection派生自定义非泛型集合ObservableCollection<MissionData>并使用它来保留MissionData个项目。然后我会在DataType中引用该集合。此解决方案提供了其他优点,例如集合上有用的事件聚合。

然而,在我看来,最好的解决方案如下。

  1. 向您的VM添加IsMissionsListVisible属性。
  2. 将显示列表的Visibility的{​​{1}}属性绑定到ContentControl属性。
  3. 使用密钥IsMissionsListVisible资源。
  4. 实施确定是否DataTemplate的逻辑。据推测,当所选项目中至少有一个任务时,它应该是真的。但逻辑可能更复杂。
  5. 我会这样做。事实上,我通常这样做,它有几个好处。最重要的是,我可以在各种情况下明确控制内容可见性的逻辑(例如,异步内容刷新)。