1

我是 WPF 新手并使用 MVVM。我有一个视图,我想根据用户在菜单上选择的内容显示不同的内容。其中之一是另一个具有视图模型(TempVM)的用户控件 Temp,所以我这样做:

<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 所做的相同模式,但它似乎过分了。我在这件事上走的是正确的道路吗?我需要做什么?

4

2 回答 2

2

据我所知,您尝试将 Collection 用作数据对象,这在我看来是不好的做法。拥有一个集合的 DataTemplate 也是有问题的,就像您已经看到的那样。我建议您为您的任务集合使用 ViewModel。

class MissionsSelectionViewModel
{
    public ObservableCollection<Mission> Misssions;
    public MissionData SelectedMission;
    public ICommand MissionSelected;
}

并将您的数据模板修改为

<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>
于 2012-04-18T09:20:24.480 回答
1

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

但是,在我看来,最好的解决方案如下。

  1. IsMissionsListVisible属性添加到您的 VM。
  2. VisibilityContentControl显示列表的属性绑定到该IsMissionsListVisible属性。
  3. 使用密钥DataTemplate资源。
  4. 实现确定 if 的逻辑IsMissionsListVisible。假设在所选项目中至少有一个任务时应该为真。但逻辑可能更复杂。

我会这样做。事实上,我通常这样做,它有几个好处。最重要的是我可以在各种情况下(例如异步内容刷新)显式控制内容可见性的逻辑。

于 2012-04-18T09:14:08.057 回答