2015-10-21 6 views
9

GridViewがあり、各項目をクリックして別のページに移動したいとします。ViewModelのビューをviewmodelまたは複数のDataTemplatesに関連付けるにはどうすればよいですか?

viewmodelに関連付けられたビューにナビゲートするにはどうすればよいですか?

WPFには、ビューモデルの複数のDatatemplateを設定する方法があります。

<TabControl Grid.Row="1" Margin="0" ItemsSource="{Binding Tabs}" SelectedIndex="0" SelectedItem="{Binding SelectedTab}"> 
    <TabControl.Resources> 
     <DataTemplate DataType="{x:Type dashboard:DashboardViewModel}"> 
      <dashboard:DashboardView/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type controls:ExchangeViewModel}"> 
      <controls:ExchangeView/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type request:RequestViewModel}"> 
      <request:RequestView/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type addresses:AddressViewModel}"> 
      <addresses:AddressView/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type settings:ExchangeSettingsViewModel}"> 
      <settings:ExchangeSettingsView/> 
     </DataTemplate> 

    </TabControl.Resources> 
    <TabControl.ItemTemplate> 
     <DataTemplate DataType="vm:ViewModelBase"> 
      <TextBlock Text="{Binding Header}" FontSize="14"></TextBlock> 
     </DataTemplate> 
    </TabControl.ItemTemplate> 
</TabControl> 

これは私が私の特定のケースでUWPにしようとしたものです:

<Frame Grid.Row="1" DataContext="{x:Bind ViewModel.Value}"> 
    <Frame.Resources> 
     <DataTemplate x:DataType="viewModels:ExampleViewModel1"> 
      <views:ExampleView1></views:ExampleView1> 
     </DataTemplate> 
     <DataTemplate x:DataType="viewModels:ExampleViewModel2"> 
      <views:ExampleView2></views:ExampleView2> 
     </DataTemplate> 
    </Frame.Resources> 
</Frame> 

フレームは、ページの一部であり、私はViewModelにの値に基づいて、対応するビューを表示したいです。

Visual Studioでは、DataTemplateにキー属性が必要ですが、ビューを作成していないためWPFと同じように機能しません。

私はDataTypeがx:DataTypeとx:Typeに置き換えられたことを知っています。同様の結果を達成する方法はありますか?

+1

あなたは 'ContentPresentを使用して考えがありますあなたのビューモデルを表示するには? –

+0

TabControlは一例に過ぎないので、私がUWPで持っているsitutionについての詳細を追加します。 – Andre

+0

この[link]のユーザーボイスにはスレッドがあります(https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/18575131-add-implicit-datatemplates-to-uwp) – Portikus

答えて

13

WPFでは、DataTypeは実行時に取得できる依存関係プロパティです。

UWPでは、x:DataTypeはコンパイル時プロパティです。実行時に値を取得できません。

DataTemplateSelectorを使用してUWPのデータ型とデータテンプレートをマッピングする方法について簡単なデモを作成しました。

DataTemplateSelector:

namespace UWPApp 
{ 
    public class Template 
    { 
     public string DataType { get; set; } 

     public DataTemplate DataTemplate { get; set; } 
    } 

    public class TemplateCollection2 : System.Collections.ObjectModel.Collection<Template> 
    { 
    } 


    public class MyDataTemplateSelector : DataTemplateSelector 
    { 
     public TemplateCollection2 Templates { get; set; } 

     private IList<Template> _templateCache { get; set; } 

     public MyDataTemplateSelector() 
     { 

     } 

     private void InitTemplateCollection() 
     { 
      _templateCache = Templates.ToList(); 
     } 

     protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) 
     { 
      if (_templateCache == null) 
      { 
       InitTemplateCollection(); 
      } 

      if(item != null) 
      { 
       var dataType = item.GetType().ToString(); 

       var match = _templateCache.Where(m => m.DataType == dataType).FirstOrDefault(); 

       if(match != null) 
       { 
        return match.DataTemplate; 
       } 
      } 

      return base.SelectTemplateCore(item, container); 
     } 
    } 
} 

のViewModel:

namespace UWPApp 
{ 
    public class ViewModel1 
    { 
     public string Text1 { get; set; } 
    } 

    public class ViewModel2 
    { 
     public string Text2 { get; set; } 
    } 
} 

XAML:

<Grid 
    x:Name="container" 
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <Grid.Resources> 
     <local:TemplateCollection2 x:Key="templates"> 
      <local:Template DataType="UWPApp.ViewModel1"> 
       <local:Template.DataTemplate> 
        <DataTemplate x:DataType="local:ViewModel1"> 
         <StackPanel> 
          <TextBlock Text="{Binding Text1}"></TextBlock> 
          <TextBlock Text="From template1"></TextBlock> 
         </StackPanel> 
        </DataTemplate> 
       </local:Template.DataTemplate> 
      </local:Template> 
      <local:Template DataType="UWPApp.ViewModel2"> 
       <local:Template.DataTemplate> 
        <DataTemplate x:DataType="local:ViewModel2"> 
         <StackPanel> 
          <TextBlock Text="{Binding Text2}"></TextBlock> 
          <TextBlock Text="From template2"></TextBlock> 
         </StackPanel> 
        </DataTemplate> 
       </local:Template.DataTemplate> 
      </local:Template> 
     </local:TemplateCollection2> 
     <local:MyDataTemplateSelector 
     x:Key="myDataTemplateSelector" Templates="{StaticResource templates}"> 
     </local:MyDataTemplateSelector> 
    </Grid.Resources> 
    <StackPanel> 
     <Button x:Name="button" Click="button_Click">Click Me</Button> 
     <ContentControl x:Name="stage" ContentTemplateSelector="{StaticResource myDataTemplateSelector}"> 

     </ContentControl> 
    </StackPanel> 
</Grid> 
+0

多くのありがとう。この仕事をするのは本当にピタです。 –

+2

私は答えをアップアップしましたが、それは問題を解決するので、信じられないようです。そのような単純な事柄には何トンもの余分なコードが必要です。マイクロソフトでは、このプラットフォームでどのように作業しているのがうれしいかと思うことがあります。それは混乱です。 :( –