2015-10-21 64 views
9

鑑於我有一個GridView,我想通過點擊每個項目導航到不同的頁面。如何將視圖與ViewModel的viewmodel或多個DataTemplates關聯?

如何導航到與視圖模型關聯的視圖?

在WPF中,有一種方法可以爲viewmodel設置多個Datatemplates。

<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> 

的構架是一個網頁的一部分,我想表明基於視圖模型的價值相應的視圖。

Visual Studio告訴我DataTemplate必須有一個鍵屬性,但即使如此,它仍然不能像在WPF中那樣工作,因爲它不會創建視圖。

我知道DataType被替換爲x:DataType和x:Type似乎不見了。有沒有辦法達到類似的結果?

+1

你有使用'ContentPresent考慮呃'顯示您的視圖模型? –

+0

我將添加更多關於我在UWP中擁有的sitution的信息,因爲TabControl僅僅是一個示例。 – Andre

+0

UserVoice上的這個[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); 
     } 
    } 
} 

視圖模型:

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

儘管我提出了答案,但它解決了這個問題,這是令人難以置信的,原理如此簡單,需要大量額外的代碼。微軟有時會讓我懷疑,他們與這個平臺合作有多幸福。一團糟。 :( –

相關問題