1

私はWPFが初めてで、MVVMを使用しています。ユーザーがメニューで選択した内容に応じて、異なるコンテンツを表示したいビューがあります。それらの1つは、ビューモデル(TempVM)を持つ別のユーザーコントロールTempであるため、これを行っています:

<ContentControl Content="{Binding Path=TempVM}"/>

TempVM (TempViewModel 型) は、ユーザーがボタンをクリックするまで null です。そのデータテンプレートはこれ

 <DataTemplate DataType="{x:Type vm:TempViewModel}">
        <view:Temp />
    </DataTemplate>

それは問題ありませんが、もう 1 つやりたいことは、ユーザーが別のメニュー項目をクリックしたときにリストボックスを表示することです。だから私はやろうとしています

<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 で行ったのと同じパターンに従うことができますが、それはやり過ぎのようです。私はこれについて正しい道を進んでいますか?何をする必要がありますか?

4

2 に答える 2

2

私が見るところ、コレクションをデータオブジェクトとして使用しようとしていますが、これは私の意見では悪い習慣です。すでに見たように、コレクションに 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. リストを表示するのVisibilityプロパティをプロパティにバインドします。ContentControlIsMissionsListVisible
  3. キー付きDataTemplateリソースを使用します。
  4. かどうかを判断するロジックを実装しIsMissionsListVisibleます。おそらく、選択したアイテムに少なくとも 1 つのミッションがある場合は true になるはずです。ただし、ロジックはより複雑になる可能性があります。

私ならこうします。実際、私は通常このようにしていますが、いくつかの利点があります。最も重要なことは、さまざまな状況 (コンテンツの非同期更新など) でコンテンツの可視性のロジックを明示的に制御できることです。

于 2012-04-18T09:14:08.057 に答える